[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f1b300lqgtfmoj":3,"$f250wz8h39yydc":8,"$f3e13fn86h0z0l":29,"$f1tmzc20p7l0cb":37,"$f1jx4dtoqs52d9":72,"toc--512084876-5-5":76},{"description":4,"domain":5,"id":6,"keywords":4,"title":7},"","api.kongjs.com",1,"默认",[9,20,24],{"children":10,"icon":4,"id":11,"linkType":12,"linkUrl":13,"parentId":14,"sort":15,"status":16,"target":17,"title":18,"visible":19},null,"447369447469600768","URL","\u002F","0",0,"1","_self","首页",true,{"children":10,"icon":4,"id":21,"linkType":12,"linkUrl":22,"parentId":14,"sort":15,"status":16,"target":17,"title":23,"visible":19},"447369693859794944","\u002Fnotes","笔记",{"children":10,"icon":4,"id":25,"linkType":26,"linkUrl":27,"parentId":14,"sort":15,"status":16,"target":17,"title":28,"visible":19},"447369977960976384","PAGE","\u002Fabout","关于我",{"category":30,"categoryId":31,"cover":10,"description":4,"fileId":10,"id":34,"publishAt":10,"tags":35,"title":36},{"articleCount":10,"children":10,"cover":10,"description":4,"fileId":10,"icon":4,"id":31,"parentId":14,"slug":32,"sort":15,"title":33},"453164732518506496","back-end","后端","453165633773772800",[],"Java面试核心知识",[38,41,44,48,52,56,60,64,68],{"children":10,"description":4,"id":39,"noteId":34,"parentId":14,"sort":15,"status":16,"title":40},"453165775620939776","Java基础核心全集（数据类型、拆箱装箱、克隆、对象结构、字符串、包装类、序列化）",{"children":10,"description":4,"id":42,"noteId":34,"parentId":14,"sort":6,"status":16,"title":43},"453166088570544128","JVM原理（JDK8~25）内存结构、分代模型、GC算法、垃圾收集器、元空间、双亲委派机制",{"children":10,"description":4,"id":45,"noteId":34,"parentId":14,"sort":46,"status":16,"title":47},"453166295265845248",2,"Java8至25 对象创建全过程及各版本底层演进差异",{"children":10,"description":4,"id":49,"noteId":34,"parentId":14,"sort":50,"status":16,"title":51},"453166545573519360",3,"Java集合全套原理（List+Map底层、扩容机制、线程安全集合对比）",{"children":10,"description":4,"id":53,"noteId":34,"parentId":14,"sort":54,"status":16,"title":55},"453166809651093504",4,"Java线程原理、六大状态流转、线程结束判断、安全中断、核心方法区别",{"children":10,"description":4,"id":57,"noteId":34,"parentId":14,"sort":58,"status":16,"title":59},"453167023724175360",5,"Java线程池原理、使用规范、常用并发异步工具类",{"children":10,"description":4,"id":61,"noteId":34,"parentId":14,"sort":62,"status":16,"title":63},"453167209447956480",6,"Java 虚拟线程与平台线程：原理、区别与实战使用",{"children":10,"description":4,"id":65,"noteId":34,"parentId":14,"sort":66,"status":16,"title":67},"453167452423987200",7,"CAS与AQS 底层原理、核心流程、面试最全详解",{"children":10,"description":4,"id":69,"noteId":34,"parentId":14,"sort":70,"status":16,"title":71},"453168570885480448",8,"线上服务器CPU飙升 Java代码 完整定位排查流程",{"content":73,"contentType":74,"description":4,"title":55,"wordCount":75},"# Java线程原理、六大状态流转、线程结束判断、安全中断、核心方法区别\n\n本文一次性吃透Java线程**底层原理、完整状态流转、线程结束判断、安全中断机制、sleep\u002Fwait\u002Fjoin\u002Fyield\u002Fpark全部区别**，解决99%线程面试问题，逻辑闭环、无废话、可直接背诵。\n\n## 一、Java线程底层原理\n\n### 1\\. 线程模型（重点）\n\nJava线程采用 **一对一内核线程模型（1:1）**：\n\n- 一个Java线程 = 绑定一条OS内核线程\n\n- 线程的调度、时间片分配、阻塞、唤醒全部由**操作系统内核**完成\n\n- JVM只负责封装、状态维护、栈内存管理\n\n**优缺点**：阻塞彻底释放CPU、并发能力强；但线程创建销毁、上下文切换成本高。\n\n### 2\\. 线程核心特性\n\n- **线程私有**：程序计数器、虚拟机栈、本地方法栈\n\n- **线程共享**：堆、方法区\n\n- 线程切换会产生**上下文切换开销**（保存\u002F恢复现场）\n\n---\n\n## 二、Java线程六大状态（JDK Thread\\.State）\n\nJava 严格定义6种状态，**没有 Running 状态**，运行中也属于 RUNNABLE。\n\n1. **NEW**：新建线程对象，未调用 start\\(\\)，无内核线程绑定\n\n2. **RUNNABLE**：可运行\u002F正在运行，等待CPU时间片或正在执行\n\n3. **BLOCKED**：等待获取 **synchronized** 互斥锁\n\n4. **WAITING**：无限等待，必须手动唤醒（无超时）\n\n5. **TIMED\\_WAITING**：限时等待，超时自动唤醒\n\n6. **TERMINATED**：线程执行完毕，彻底死亡\n\n## 三、完整状态流转（面试必背链路）\n\n**核心主线**：NEW → start\\(\\) → RUNNABLE → 执行业务代码 → TERMINATED\n\n**四大分支阻塞流转**：\n\n- **RUNNABLE \\-\\-抢锁失败\\-\\-\\> BLOCKED**：抢到锁回到RUNNABLE\n\n- **RUNNABLE \\-\\-wait\\(\\)\u002Fjoin\\(\\)\u002Fpark\\(\\)\\-\\-\\> WAITING**：notify\u002FnotifyAll\u002Funpark 唤醒\n\n- **RUNNABLE \\-\\-sleep\\(\\)\u002Fwait\\(时间\\)\\-\\-\\> TIMED\\_WAITING**：超时自动唤醒\n\n- 所有阻塞唤醒后，一律回到 **RUNNABLE**\n\n### 关键区分（高频坑点）\n\n- **BLOCKED**：只有 synchronized 锁竞争才会触发\n\n- **WAITING\u002FTIMED\\_WAITING**：主动休眠、挂起，**释放CPU**\n\n---\n\n## 四、如何判断线程是否执行完成？（4种方案）\n\n### 1\\. isAlive\\(\\)\n\ntrue=线程存活（未结束），false=未启动\u002F已结束。\n\n### 2\\. getState\\(\\) == TERMINATED\n\n最精准，直接判断线程终止状态。\n\n### 3\\. join\\(\\) 阻塞等待\n\n主线程阻塞，直到目标线程执行完毕。适合单线程等待。\n\n### 4\\. CountDownLatch \u002F CyclicBarrier\n\n多线程场景最优，精准等待一批线程全部执行完成。\n\n---\n\n## 五、线程安全中断机制（核心重点）\n\n### 1\\. 核心结论：stop\\(\\) 强制终止 **废弃、不安全**\n\nstop\\(\\) 会直接杀死线程、丢失数据、破坏事务一致性，生产绝对禁止使用。\n\n### 2\\. Java 安全中断原理（协作式中断）\n\nJava线程中断是 **协作式、软中断**：\n\n- `interrupt()`：只是**打一个中断标记**，不会立刻终止线程\n\n- 线程是否退出，由线程**自己判断标记、自主决定**\n\n### 3\\. 三个中断核心方法\n\n- **interrupt\\(\\)**：设置中断标志位为true\n\n- **isInterrupted\\(\\)**：判断是否中断，**不清除标志位**\n\n- **Thread\\.interrupted\\(\\)**：判断是否中断，**清除标志位（静态方法）**\n\n### 4\\. 阻塞线程的中断特性（高频考点）\n\n当线程处于 **sleep\u002Fwait\u002Fjoin** 阻塞状态：\n\n调用 interrupt\\(\\) → **直接抛出 InterruptedException**，并**清空中断标志位**\n\n### 5\\. 标准安全中断写法\n\n```java\nwhile(!Thread.currentThread().isInterrupted()){\n    \u002F\u002F 执行业务逻辑\n}\n\u002F\u002F 收到中断信号，优雅收尾、释放资源、退出线程\n\n```\n\n### 6\\. 为什么要设计成协作式中断？\n\n为了**线程安全**：让线程可以收尾逻辑、释放锁、释放连接、保证数据一致性，不会被暴力杀死导致数据错乱。\n\n---\n\n## 六、线程核心方法原理 \\& 终极区别（面试必考）\n\n### 1\\. sleep\\(\\) 原理\n\n- 让线程进入 **TIMED\\_WAITING**\n\n- **不释放锁**（synchronized、lock 都不释放）\n\n- 时间到自动唤醒\n\n- 可被中断抛异常\n\n### 2\\. wait\\(\\) 原理（Object方法）\n\n- 必须在同步代码块中执行\n\n- 进入 **WAITING** 状态\n\n- **强制释放锁**\n\n- 必须 notify\u002FnotifyAll 唤醒\n\n### 3\\. join\\(\\) 原理\n\n- 主线程等待子线程执行完毕\n\n- 底层是 wait 实现，**会释放锁**\n\n- 进入 WAITING\u002FTIMED\\_WAITING\n\n### 4\\. yield\\(\\) 原理\n\n- 礼让CPU，当前线程主动让出时间片\n\n- **状态不变，仍是 RUNNABLE**\n\n- **不释放锁**\n\n- 只是降低自己优先级，可能再次抢到CPU\n\n### 5\\. park\\(\\) 原理（LockSupport）\n\n- AQS 底层阻塞工具\n\n- 进入 WAITING 状态\n\n- **不依赖锁**、精准唤醒、不会丢失信号\n\n- 支持中断、不抛异常，只返回中断状态\n\n---\n\n## 七、方法终极对比表（背诵版）\n\n|方法|是否释放锁|状态|唤醒方式|\n|---|---|---|---|\n|sleep|不释放|TIMED\\_WAITING|超时\u002F中断|\n|wait|**释放锁**|WAITING|notify|\n|join|**释放锁**|WAITING|线程结束|\n|yield|不释放|RUNNABLE|自动重新竞争|\n|park|不释放|WAITING|unpark\u002F中断|\n\n---\n\n## 八、面试一句话终极总结（直接背诵）\n\n- **线程原理**：Java线程是1:1内核线程，由OS调度，拥有独立栈空间，共享堆内存。\n\n- **状态流转**：六大状态核心区分阻塞类型，锁阻塞是BLOCKED，主动等待是WAITING\u002FTIMED\\_WAITING。\n\n- **线程结束**：可通过状态判断、isAlive、join、CountDownLatch四种方式确认。\n\n- **安全中断**：采用协作式中断，interrupt仅打标记，线程自主判断退出，禁止stop暴力终止。\n\n- **方法区别**：sleep不释放锁、wait释放锁、yield只是礼让、join等待线程结束、park精准阻塞。","markdown",3193,{"frontmatter":77,"meta":78,"nodes":164},{},{"title":55,"description":79,"toc":80},"本文一次性吃透Java线程底层原理、完整状态流转、线程结束判断、安全中断机制、sleep\u002Fwait\u002Fjoin\u002Fyield\u002Fpark全部区别，解决99%线程面试问题，逻辑闭环、无废话、可直接背诵。",{"title":4,"searchDepth":58,"depth":58,"links":81},[82,92,95,101,117,139,158,161],{"id":83,"depth":46,"text":84,"children":85},"java-1","一、Java线程底层原理",[86,89],{"id":87,"depth":50,"text":88},"java-_1","1. 线程模型（重点）",{"id":90,"depth":50,"text":91},"java-_2","2. 线程核心特性",{"id":93,"depth":46,"text":94},"javajdk-threadstate","二、Java线程六大状态（JDK Thread.State）",{"id":4,"depth":46,"text":96,"children":97},"三、完整状态流转（面试必背链路）",[98],{"id":99,"depth":50,"text":100},"-","关键区分（高频坑点）",{"id":102,"depth":46,"text":103,"children":104},"_4","四、如何判断线程是否执行完成？（4种方案）",[105,108,111,114],{"id":106,"depth":50,"text":107},"_4-_1-isalive","1. isAlive()",{"id":109,"depth":50,"text":110},"_4-_2-getstate-terminated","2. getState() == TERMINATED",{"id":112,"depth":50,"text":113},"_4-_3-join","3. join() 阻塞等待",{"id":115,"depth":50,"text":116},"_4-_4-countdownlatch-cyclicbarrier","4. CountDownLatch \u002F CyclicBarrier",{"id":118,"depth":46,"text":119,"children":120},"-1","五、线程安全中断机制（核心重点）",[121,124,127,130,133,136],{"id":122,"depth":50,"text":123},"-_1-stop","1. 核心结论：stop() 强制终止 废弃、不安全",{"id":125,"depth":50,"text":126},"-_2-java","2. Java 安全中断原理（协作式中断）",{"id":128,"depth":50,"text":129},"-_3","3. 三个中断核心方法",{"id":131,"depth":50,"text":132},"-_4","4. 阻塞线程的中断特性（高频考点）",{"id":134,"depth":50,"text":135},"-_5","5. 标准安全中断写法",{"id":137,"depth":50,"text":138},"-_6","6. 为什么要设计成协作式中断？",{"id":140,"depth":46,"text":141,"children":142},"-2","六、线程核心方法原理 & 终极区别（面试必考）",[143,146,149,152,155],{"id":144,"depth":50,"text":145},"-_1-sleep","1. sleep() 原理",{"id":147,"depth":50,"text":148},"-_2-wait-object","2. wait() 原理（Object方法）",{"id":150,"depth":50,"text":151},"-_3-join","3. join() 原理",{"id":153,"depth":50,"text":154},"-_4-yield","4. yield() 原理",{"id":156,"depth":50,"text":157},"-_5-park-locksupport","5. park() 原理（LockSupport）",{"id":159,"depth":46,"text":160},"-3","七、方法终极对比表（背诵版）",{"id":162,"depth":46,"text":163},"-4","八、面试一句话终极总结（直接背诵）",[165,169,178,181,184,191,208,214,216,237,240,242,249,292,294,300,305,330,332,348,350,352,354,357,359,362,364,367,369,372,374,376,382,385,387,393,412,414,438,440,447,457,459,466,468,475,477,479,481,500,502,521,523,537,539,556,558,575,577,579,671,673,675],[166,167,55],"h1",{"id":168},"java",[170,171,172,173,177],"p",{},"本文一次性吃透Java线程",[174,175,176],"strong",{},"底层原理、完整状态流转、线程结束判断、安全中断机制、sleep\u002Fwait\u002Fjoin\u002Fyield\u002Fpark全部区别","，解决99%线程面试问题，逻辑闭环、无废话、可直接背诵。",[179,180,84],"h2",{"id":83},[182,183,88],"h3",{"id":87},[170,185,186,187,190],{},"Java线程采用 ",[174,188,189],{},"一对一内核线程模型（1:1）","：",[192,193,194,198,205],"ul",{},[195,196,197],"li",{},"一个Java线程 = 绑定一条OS内核线程",[195,199,200,201,204],{},"线程的调度、时间片分配、阻塞、唤醒全部由",[174,202,203],{},"操作系统内核","完成",[195,206,207],{},"JVM只负责封装、状态维护、栈内存管理",[170,209,210,213],{},[174,211,212],{},"优缺点","：阻塞彻底释放CPU、并发能力强；但线程创建销毁、上下文切换成本高。",[182,215,91],{"id":90},[192,217,218,224,230],{},[195,219,220,223],{},[174,221,222],{},"线程私有","：程序计数器、虚拟机栈、本地方法栈",[195,225,226,229],{},[174,227,228],{},"线程共享","：堆、方法区",[195,231,232,233,236],{},"线程切换会产生",[174,234,235],{},"上下文切换开销","（保存\u002F恢复现场）",[238,239],"hr",{},[179,241,94],{"id":93},[170,243,244,245,248],{},"Java 严格定义6种状态，",[174,246,247],{},"没有 Running 状态","，运行中也属于 RUNNABLE。",[250,251,252,258,264,274,280,286],"ol",{},[195,253,254,257],{},[174,255,256],{},"NEW","：新建线程对象，未调用 start()，无内核线程绑定",[195,259,260,263],{},[174,261,262],{},"RUNNABLE","：可运行\u002F正在运行，等待CPU时间片或正在执行",[195,265,266,269,270,273],{},[174,267,268],{},"BLOCKED","：等待获取 ",[174,271,272],{},"synchronized"," 互斥锁",[195,275,276,279],{},[174,277,278],{},"WAITING","：无限等待，必须手动唤醒（无超时）",[195,281,282,285],{},[174,283,284],{},"TIMED_WAITING","：限时等待，超时自动唤醒",[195,287,288,291],{},[174,289,290],{},"TERMINATED","：线程执行完毕，彻底死亡",[179,293,96],{"id":4},[170,295,296,299],{},[174,297,298],{},"核心主线","：NEW → start() → RUNNABLE → 执行业务代码 → TERMINATED",[170,301,302,190],{},[174,303,304],{},"四大分支阻塞流转",[192,306,307,313,319,325],{},[195,308,309,312],{},[174,310,311],{},"RUNNABLE --抢锁失败--> BLOCKED","：抢到锁回到RUNNABLE",[195,314,315,318],{},[174,316,317],{},"RUNNABLE --wait()\u002Fjoin()\u002Fpark()--> WAITING","：notify\u002FnotifyAll\u002Funpark 唤醒",[195,320,321,324],{},[174,322,323],{},"RUNNABLE --sleep()\u002Fwait(时间)--> TIMED_WAITING","：超时自动唤醒",[195,326,327,328],{},"所有阻塞唤醒后，一律回到 ",[174,329,262],{},[182,331,100],{"id":99},[192,333,334,339],{},[195,335,336,338],{},[174,337,268],{},"：只有 synchronized 锁竞争才会触发",[195,340,341,344,345],{},[174,342,343],{},"WAITING\u002FTIMED_WAITING","：主动休眠、挂起，",[174,346,347],{},"释放CPU",[238,349],{},[179,351,103],{"id":102},[182,353,107],{"id":106},[170,355,356],{},"true=线程存活（未结束），false=未启动\u002F已结束。",[182,358,110],{"id":109},[170,360,361],{},"最精准，直接判断线程终止状态。",[182,363,113],{"id":112},[170,365,366],{},"主线程阻塞，直到目标线程执行完毕。适合单线程等待。",[182,368,116],{"id":115},[170,370,371],{},"多线程场景最优，精准等待一批线程全部执行完成。",[238,373],{},[179,375,119],{"id":118},[182,377,378,379],{"id":122},"1. 核心结论：stop() 强制终止 ",[174,380,381],{},"废弃、不安全",[170,383,384],{},"stop() 会直接杀死线程、丢失数据、破坏事务一致性，生产绝对禁止使用。",[182,386,126],{"id":125},[170,388,389,390,190],{},"Java线程中断是 ",[174,391,392],{},"协作式、软中断",[192,394,395,406],{},[195,396,397,401,402,405],{},[398,399,400],"code",{},"interrupt()","：只是",[174,403,404],{},"打一个中断标记","，不会立刻终止线程",[195,407,408,409],{},"线程是否退出，由线程",[174,410,411],{},"自己判断标记、自主决定",[182,413,129],{"id":128},[192,415,416,421,430],{},[195,417,418,420],{},[174,419,400],{},"：设置中断标志位为true",[195,422,423,426,427],{},[174,424,425],{},"isInterrupted()","：判断是否中断，",[174,428,429],{},"不清除标志位",[195,431,432,426,435],{},[174,433,434],{},"Thread.interrupted()",[174,436,437],{},"清除标志位（静态方法）",[182,439,132],{"id":131},[170,441,442,443,446],{},"当线程处于 ",[174,444,445],{},"sleep\u002Fwait\u002Fjoin"," 阻塞状态：",[170,448,449,450,453,454],{},"调用 interrupt() → ",[174,451,452],{},"直接抛出 InterruptedException","，并",[174,455,456],{},"清空中断标志位",[182,458,135],{"id":134},[460,461,462],"pre",{"language":168},[398,463,465],{"class":464},"language-java","while(!Thread.currentThread().isInterrupted()){\n    \u002F\u002F 执行业务逻辑\n}\n\u002F\u002F 收到中断信号，优雅收尾、释放资源、退出线程\n",[182,467,138],{"id":137},[170,469,470,471,474],{},"为了",[174,472,473],{},"线程安全","：让线程可以收尾逻辑、释放锁、释放连接、保证数据一致性，不会被暴力杀死导致数据错乱。",[238,476],{},[179,478,141],{"id":140},[182,480,145],{"id":144},[192,482,483,488,494,497],{},[195,484,485,486],{},"让线程进入 ",[174,487,284],{},[195,489,490,493],{},[174,491,492],{},"不释放锁","（synchronized、lock 都不释放）",[195,495,496],{},"时间到自动唤醒",[195,498,499],{},"可被中断抛异常",[182,501,148],{"id":147},[192,503,504,507,513,518],{},[195,505,506],{},"必须在同步代码块中执行",[195,508,509,510,512],{},"进入 ",[174,511,278],{}," 状态",[195,514,515],{},[174,516,517],{},"强制释放锁",[195,519,520],{},"必须 notify\u002FnotifyAll 唤醒",[182,522,151],{"id":150},[192,524,525,528,534],{},[195,526,527],{},"主线程等待子线程执行完毕",[195,529,530,531],{},"底层是 wait 实现，",[174,532,533],{},"会释放锁",[195,535,536],{},"进入 WAITING\u002FTIMED_WAITING",[182,538,154],{"id":153},[192,540,541,544,549,553],{},[195,542,543],{},"礼让CPU，当前线程主动让出时间片",[195,545,546],{},[174,547,548],{},"状态不变，仍是 RUNNABLE",[195,550,551],{},[174,552,492],{},[195,554,555],{},"只是降低自己优先级，可能再次抢到CPU",[182,557,157],{"id":156},[192,559,560,563,566,572],{},[195,561,562],{},"AQS 底层阻塞工具",[195,564,565],{},"进入 WAITING 状态",[195,567,568,571],{},[174,569,570],{},"不依赖锁","、精准唤醒、不会丢失信号",[195,573,574],{},"支持中断、不抛异常，只返回中断状态",[238,576],{},[179,578,160],{"id":159},[580,581,582,601],"table",{},[583,584,585],"thead",{},[586,587,588,592,595,598],"tr",{},[589,590,591],"th",{},"方法",[589,593,594],{},"是否释放锁",[589,596,597],{},"状态",[589,599,600],{},"唤醒方式",[602,603,604,618,633,647,659],"tbody",{},[586,605,606,610,613,615],{},[607,608,609],"td",{},"sleep",[607,611,612],{},"不释放",[607,614,284],{},[607,616,617],{},"超时\u002F中断",[586,619,620,623,628,630],{},[607,621,622],{},"wait",[607,624,625],{},[174,626,627],{},"释放锁",[607,629,278],{},[607,631,632],{},"notify",[586,634,635,638,642,644],{},[607,636,637],{},"join",[607,639,640],{},[174,641,627],{},[607,643,278],{},[607,645,646],{},"线程结束",[586,648,649,652,654,656],{},[607,650,651],{},"yield",[607,653,612],{},[607,655,262],{},[607,657,658],{},"自动重新竞争",[586,660,661,664,666,668],{},[607,662,663],{},"park",[607,665,612],{},[607,667,278],{},[607,669,670],{},"unpark\u002F中断",[238,672],{},[179,674,163],{"id":162},[192,676,677,683,689,694,700],{},[195,678,679,682],{},[174,680,681],{},"线程原理","：Java线程是1:1内核线程，由OS调度，拥有独立栈空间，共享堆内存。",[195,684,685,688],{},[174,686,687],{},"状态流转","：六大状态核心区分阻塞类型，锁阻塞是BLOCKED，主动等待是WAITING\u002FTIMED_WAITING。",[195,690,691,693],{},[174,692,646],{},"：可通过状态判断、isAlive、join、CountDownLatch四种方式确认。",[195,695,696,699],{},[174,697,698],{},"安全中断","：采用协作式中断，interrupt仅打标记，线程自主判断退出，禁止stop暴力终止。",[195,701,702,705],{},[174,703,704],{},"方法区别","：sleep不释放锁、wait释放锁、yield只是礼让、join等待线程结束、park精准阻塞。"]