生命周期
1 整体生命周期状态图
经典图:清晰区分 NEW → RUNNABLE(就绪+运行)→ BLOCKED / WAITING / TIMED_WAITING → TERMINATED,并标注了所有进入方式。

五状态经典图:新建 → 就绪 → 运行 → 阻塞 → 死亡。

超级详细版(带文字说明):把就绪细分为“等待CPU”和“运行中”,阻塞分为各种场景,非常适合深入理解。
#mermaid-svg-jvGw7XGKrhRKPI0b{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jvGw7XGKrhRKPI0b .error-icon{fill:#552222;}#mermaid-svg-jvGw7XGKrhRKPI0b .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jvGw7XGKrhRKPI0b .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jvGw7XGKrhRKPI0b .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jvGw7XGKrhRKPI0b .marker.cross{stroke:#333333;}#mermaid-svg-jvGw7XGKrhRKPI0b svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jvGw7XGKrhRKPI0b p{margin:0;}#mermaid-svg-jvGw7XGKrhRKPI0b defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-jvGw7XGKrhRKPI0b g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-jvGw7XGKrhRKPI0b g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-jvGw7XGKrhRKPI0b g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-jvGw7XGKrhRKPI0b g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-jvGw7XGKrhRKPI0b g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-jvGw7XGKrhRKPI0b .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-jvGw7XGKrhRKPI0b .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-jvGw7XGKrhRKPI0b .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-jvGw7XGKrhRKPI0b .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-jvGw7XGKrhRKPI0b .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-jvGw7XGKrhRKPI0b .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-jvGw7XGKrhRKPI0b .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-jvGw7XGKrhRKPI0b .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jvGw7XGKrhRKPI0b .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jvGw7XGKrhRKPI0b .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jvGw7XGKrhRKPI0b .edgeLabel .label text{fill:#333;}#mermaid-svg-jvGw7XGKrhRKPI0b .label div .edgeLabel{color:#333;}#mermaid-svg-jvGw7XGKrhRKPI0b .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-jvGw7XGKrhRKPI0b .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-jvGw7XGKrhRKPI0b .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-jvGw7XGKrhRKPI0b .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-jvGw7XGKrhRKPI0b .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-jvGw7XGKrhRKPI0b .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jvGw7XGKrhRKPI0b .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jvGw7XGKrhRKPI0b #statediagram-barbEnd{fill:#333333;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jvGw7XGKrhRKPI0b .cluster-label,#mermaid-svg-jvGw7XGKrhRKPI0b .nodeLabel{color:#131300;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-jvGw7XGKrhRKPI0b .note-edge{stroke-dasharray:5;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-note text{fill:black;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram-note .nodeLabel{color:black;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagram .edgeLabel{color:red;}#mermaid-svg-jvGw7XGKrhRKPI0b #dependencyStart,#mermaid-svg-jvGw7XGKrhRKPI0b #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-jvGw7XGKrhRKPI0b .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jvGw7XGKrhRKPI0b :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
new Thread()
start()
等待 synchronized 锁
获取到锁
wait() / join()
sleep() / wait(time)
notify() / interrupt()
时间到 / interrupt()
run() 执行完毕
极少见,通常先变 RUNNABLE
极少见
极少见
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED

线程生命周期核心规则:
状态单向不可逆
一旦线程调用 start() 进入 RUNNABLE,就永远回不到 NEW;一旦到达 TERMINATED,就再也无法进入任何其他状态(终态,不可复活)。
同一个线程对象只能 start() 一次
第二次调用 start() 会直接抛出 IllegalThreadStateException(一生只能启动一次)。
RUNNABLE 是“万能中转站”
几乎所有状态转换都要经过 RUNNABLE(包括就绪+运行两种OS层面状态,JVM不细分);NEW → RUNNABLE → 各种阻塞/等待 → RUNNABLE → TERMINATED 是最典型路径。
阻塞与等待的唤醒依赖外部事件
- BLOCKED(synchronized锁竞争)→ 自动靠获得锁转为RUNNABLE
- WAITING → 必须被 notify/notifyAll、unpark 或 被join的线程结束 唤醒
- TIMED_WAITING → 除上述外,还可以靠时间到达自动唤醒
程序员无法“强行把线程从等待中拽出来”,必须靠这些触发条件。
禁止使用 stop()、suspend()、resume()
这几个方法早在 JDK 1.2 就标记为Deprecated,极不安全:
- stop() 会直接杀死线程,可能导致资源不释放、对象处于不一致状态
- suspend() 会让线程永久挂起而不释放锁,极易死锁
现代推荐做法:用 interrupt() + 主动检查中断标志(isInterrupted() / Thread.interrupted())来协作式终止线程。

interrupt() 只是“礼貌请求”中断,不是强制杀死
- 仅对处于 sleep()、wait()、join()、park() 等可中断方法的线程会抛出 InterruptedException
- 对普通运行代码无直接效果,必须由线程自己检查中断状态并主动退出
(这是“优雅关闭线程”的核心原则)
run() 执行结束或未捕获异常 = 死亡
线程的 TERMINATED 状态只能通过 run() 方法正常返回 或 抛出未捕获异常两种方式到达,没有其他途径。
2 各状态详细说明
总结:
新建 → start() → 就绪 → 获取CPU → 运行
运行 →
- sleep/wait/join/park/synchronized拿不到锁 → 阻塞
- yield()/时间片结束 → 就绪
- run()结束/异常 → 终止
阻塞 → 时间到/notify/unpark/锁释放 → 就绪
(1)新建状态(New)
-
特征:线程对象已被 new 创建,但还未调用 start() 方法。同一个线程对象不能多次调用 start () 方法,否则会抛出IllegalThreadStateException异常。

-
此时线程:还没有被 JVM 分配资源(栈空间、程序计数器等),本质上只是一个普通 Java 对象。
-
能做什么:只能调用 start(),不能调用 run()(直接调用 run() 只是普通方法,不会启动新线程)。
-
代码示例:
Thread t = new Thread(() -> {
System.out.println("我正在运行");
}); // ← 此时处于 New 状态
状态流转:new Thread() → 新建 → t.start() → 就绪
(2)就绪状态(Runnable / Ready)
- 特征:已调用 start(),线程已经准备好运行,等待操作系统分配 CPU 时间片。
- 注意:Java 官方 Thread.State 中把就绪 + 运行合并为一个 RUNNABLE 状态,但国内通常把它们拆开讲解。
- 此时线程:在就绪队列中排队,具备运行的一切条件,只差 CPU。
- 代码示例:
t.start(); // ← 调用后立即进入就绪状态
状态流转:
- 就绪 → 获得 CPU → 运行
- 运行中被抢占 / yield() / 时间片用完 → 回到 就绪
(3)运行状态(Running)
- 特征:线程已获得 CPU 时间片,正在真正执行 run() 方法中的代码。
- 此时线程:是 CPU 的“宠儿”,正在跑业务逻辑。
- 可能被打断的情况:
- 时间片用完(最常见)
- 调用 Thread.yield()(主动让出)
- 被更高优先级线程抢占
- 执行到阻塞操作(如 sleep、wait、synchronized 拿不到锁)
状态流转:
- 运行 → 执行完毕或异常 → 终止
- 运行 → 遇到阻塞操作 → 阻塞
(4)阻塞状态(Blocked / Waiting / Timed Waiting)
这是面试最爱深挖的部分。阻塞不是一个单一状态,而是三大类:
| Blocked | BLOCKED | 竞争 synchronized 锁失败 | 其他线程释放锁 | 等待锁(monitor) |
| Waiting | WAITING | obj.wait()、thread.join()、LockSupport.park() | notify()/notifyAll()、unpark()、join线程结束 | 无限期等待 |
| Timed Waiting | TIMED_WAITING | Thread.sleep()、wait(timeout)、join(timeout)、parkNanos() | 时间到 或 被提前唤醒 | 有超时时间 |
代码示例(三大阻塞):
// 1. BLOCKED(锁阻塞)
synchronized (obj) {
// 如果其他线程已经拿到锁,这里就会进入 BLOCKED
}
// 2. WAITING(无限等待)
synchronized (obj) {
obj.wait(); // 必须在 synchronized 中调用
}
// 3. TIMED_WAITING(限时等待)
Thread.sleep(2000); // 最常见
obj.wait(2000);
t.join(5000);
重要区别记忆口诀:
- Blocked = 等锁(synchronized)
- Waiting = 主动“喊暂停”(wait/park/join),需要别人叫醒
- Timed Waiting = “喊暂停但带闹钟”(sleep/wait+timeout)
状态流转:所有阻塞 → 条件满足 → 回到 就绪
(5)终止状态(Terminated)
- 特征:线程 run() 方法正常结束、抛出未捕获异常、或被 stop()(已废弃,不推荐)。
- 此时线程:彻底死亡,资源被回收,不能再 start()(会抛 IllegalThreadStateException)。
- 代码示例:
// run() 执行完自动进入 Terminated
// 或线程内抛出 RuntimeException 未捕获
状态流转:不可逆!终止后无法回到任何其他状态。
3 代码演示
package Thread_Lifecycle;
/**
* 线程生命周期状态演示类
* 展示Java线程的6种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
*/
public class ThreadStateDemo {
// 定义一个共享对象锁,用于演示线程同步和阻塞状态
private static final Object lock = new Object();
/**
* 主方法 – 演示各种线程状态
* @param args 命令行参数
* @throws InterruptedException 当线程被中断时抛出
*/
public static void main(String[] args) throws InterruptedException {
// 1. NEW 状态演示
// 创建线程对象但未调用start()方法,此时线程处于NEW状态
Thread t1 = new Thread(() -> {
// 线程执行体 – 实际工作代码
System.out.println("t1 进入运行状态…");
try {
// 此时线程进入TIMED_WAITING状态
Thread.sleep(200);
} catch (InterruptedException e) {
// 处理中断异常情况
System.out.println("t1 被中断");
}
// 线程执行完毕,即将进入TERMINATED状态
System.out.println("t1 执行结束 → TERMINATED");
}, "t1"); // 给线程命名,便于识别和调试
// 获取并打印线程创建后的初始状态(应该是NEW)
System.out.println("t1 创建后状态: " + t1.getState());
// 2. RUNNABLE状态演示
// 调用start()方法启动线程,线程进入RUNNABLE状态(就绪态)
// JVM调度器会很快将其分配CPU时间片开始执行
t1.start();
// 主线程休眠100毫秒,给t1线程时间开始执行
Thread.sleep(100);
// 此时t1应该已经在执行sleep()方法,处于TIMED_WAITING状态
System.out.println("t1 start 后状态: " + t1.getState());
// 3. BLOCKED状态演示(锁竞争场景)
// 创建第一个线程t2,它会获取lock对象的监视器锁
Thread t2 = new Thread(() -> {
// 使用synchronized关键字获取lock对象的内置锁
synchronized (lock) {
System.out.println("t2 拿到锁,正在执行…");
try {
// 持有锁的情况下休眠0.3秒,期间其他线程无法获取该锁
Thread.sleep(300);
} catch (InterruptedException ignored) {
// 忽略中断异常
}
}
// synchronized块结束时自动释放锁
}, "t2");
// 创建第二个线程t3,它也会尝试获取同一个lock对象的锁
Thread t3 = new Thread(() -> {
// 当t2持有锁时,t3执行到这里会被阻塞
// 因为无法获取已被t2占用的锁,进入BLOCKED状态
synchronized (lock) {
System.out.println("t3 拿到锁");
}
}, "t3");
// 启动t2线程,让它先获取锁
t2.start();
// 等待200毫秒确保t2已经获取到锁
Thread.sleep(200);
// 启动t3线程,此时t3会因为锁被占用而进入BLOCKED状态
t3.start();
// 等待300毫秒让t3充分体验BLOCKED状态
Thread.sleep(300);
// 打印t3的状态,应该显示为BLOCKED
System.out.println("t3 状态(应为 BLOCKED): " + t3.getState());
// 4. WAITING状态演示(使用Object.wait()方法)
// 创建t4线程用于演示无限期等待状态
Thread t4 = new Thread(() -> {
// 获取lock对象的锁
synchronized (lock) {
try {
System.out.println("t4 进入 wait → WAITING");
// 调用wait()方法释放锁并进入无限期等待状态
// 直到其他线程调用notify()/notifyAll()才会唤醒
lock.wait();
} catch (InterruptedException e) {
// 处理可能的中断异常
e.printStackTrace();
}
}
}, "t4");
// 启动t4线程
t4.start();
// 等待500毫秒确保t4进入WAITING状态
Thread.sleep(500);
// 打印t4状态,应该显示为WAITING
System.out.println("t4 状态(应为 WAITING): " + t4.getState());
// 唤醒处于WAITING状态的t4线程
// 需要先获取相同的锁对象才能调用notify()
synchronized (lock) {
// 唤醒在lock对象上等待的单个线程(t4)
lock.notify();
}
// 5. TIMED_WAITING状态演示(使用带超时的join方法)
// 创建t5线程用于演示定时等待
Thread t5 = new Thread(() -> {
try {
// t5线程简单地休眠0.5秒
Thread.sleep(500);
} catch (InterruptedException ignored) {
// 忽略中断异常
}
}, "t5");
// 启动t5线程
t5.start();
// 获取当前主线程的引用
Thread main = Thread.currentThread();
// 创建一个辅助线程来演示主线程的TIMED_WAITING状态
new Thread(() -> {
try {
// 调用t5.join(2000)使当前线程(辅助线程)等待t5线程最多0.2秒
// 如果2秒内t5没有结束,则继续执行
// 调用线程在此期间进入TIMED_WAITING状态
t5.join(500);
} catch (InterruptedException e) {
// 处理中断异常
e.printStackTrace();
}
}).start();
// 等待500毫秒确保辅助线程已经开始等待
Thread.sleep(500);
// 打印主线程状态,应该显示为TIMED_WAITING
System.out.println("主线程在 join(2000) 时状态: " + main.getState());
// 等待所有演示线程完成执行
// join()方法使当前线程(main线程)等待指定线程执行完毕
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
// 打印t1线程的最终状态,应该是TERMINATED
System.out.println("t1 最终状态: " + t1.getState());
}
}

4 wait() 和 sleep() 的 8 大区别(面试必问)
口诀总结:“wait会放锁睡大觉,别人叫醒才起床;sleep抱锁睡小觉,时间一到自己醒。”
| 1 | 所属类 | Object | Thread | wait是对象的,sleep是线程的 |
| 2 | 使用环境 | 必须在 synchronized 块/方法内 | 无需 synchronized | wait必须“有锁” |
| 3 | 是否释放锁 | 释放当前持有的锁 | 不释放锁 | wait会放锁,sleep死抓着 |
| 4 | 唤醒方式 | notify/notifyAll 或 interrupt | 时间到自动醒,或 interrupt | wait靠别人,sleep靠闹钟 |
| 5 | 是否可超时 | 有重载 wait(long timeout) | 有 sleep(long millis) | 两者都可带时间 |
| 6 | 中断响应 | 抛 InterruptedException 并清除中断标志 | 抛 InterruptedException 并清除中断标志 | 行为一致 |
| 7 | 所属状态(最典型) | WAITING 或 TIMED_WAITING | TIMED_WAITING | sleep一定是限时等待 |
| 8 | 假唤醒(spurious wakeup) | 可能发生,必须放在 while 循环中判断条件 | 不存在假唤醒 | wait要防“骗醒” |
5 Thread.State 枚举源码分析
理解线程状态流转对于排查死锁和性能问题至关重要。Java 线程主要有以下 6 种状态(基于 Thread.State 枚举):
public class Thread implements Runnable {
public enum State {
/**线程尚未启动。还未调用 start()。*/
NEW,
/**线程在 JVM 中执行中(包括就绪 + 真正运行 + OS 调度相关等待)。
* 这是最宽泛的状态。*/
RUNNABLE,
/** 线程在等待 monitor 锁(synchronized 块/方法)。
* 典型场景:竞争 synchronized 锁失败。*/
BLOCKED,
/** 线程在无限期等待另一个线程执行特定动作。
* 典型:wait()、join()、LockSupport.park()*/
WAITING,
/** 线程在有限时间内等待另一个线程执行特定动作。
* 典型:sleep()、wait(timeout)、join(timeout)、parkNanos、parkUntil*/
TIMED_WAITING,
/**线程已终止(run()正常结束或异常结束)。
* 不可再 start()。*/
TERMINATED;
}
}

6 Java线程状态与操作系统内核线程的对应关系
| NEW | 无(尚未创建内核线程) | Java 层只是对象,start() 后才真正创建 pthread / kernel thread |
| RUNNABLE | Ready / Running | 就绪队列中等待调度 或 正在 CPU 上执行 |
| BLOCKED | Waiting (for mutex / monitor) | 等待互斥锁(synchronized 底层是 monitorenter) |
| WAITING | Waiting / Suspended / Parked | 等待条件变量(wait/notify 底层是条件变量)、futex wait、park 等 |
| TIMED_WAITING | Waiting with timeout | 同上,但设置了超时(sleep、wait(timeout)、pthread_cond_timedwait 等) |
| TERMINATED | Zombie → Dead | 线程结束,等待被 join 或系统回收资源 |
总结对应规律:
-
Java 故意简化了状态(RUNNABLE 合并就绪+运行),隐藏了操作系统细节
-
BLOCKED 是最“重”的阻塞(与锁相关),其他都是“轻量级”等待
-
现代 JVM(HotSpot)底层大量使用 park/unpark(基于 futex / semaphore 等),而不是传统条件变量
Grok给出:



import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadStateDemo {
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws Exception {
// 1. NEW 状态(创建但未start)
Thread tNew = new Thread(() -> {}, "t-new");
printThreadInfo(tNew, "刚new出来");
// 2. RUNNABLE(正在计算或ready)
Thread tRunnable = new Thread(() -> {
long start = System.currentTimeMillis();
while (true) {
if (System.currentTimeMillis() – start > 20_000) break;
Math.sin(Math.random()); // 占用CPU
}
}, "t-runnable");
tRunnable.start();
Thread.sleep(800); // 让它跑起来
printThreadInfo(tRunnable, "RUNNABLE – 忙循环");
// 3. BLOCKED(synchronized争锁)
Thread tBlocked = new Thread(() -> {
synchronized (ThreadStateDemo.class) {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(30));
}
}, "t-blocked");
// 先让主线程持有锁
synchronized (ThreadStateDemo.class) {
tBlocked.start();
Thread.sleep(800);
printThreadInfo(tBlocked, "BLOCKED – 争synchronized锁");
}
// 4. WAITING(Object.wait() 无超时)
Thread tWaiting = new Thread(() -> {
synchronized (ThreadStateDemo.class) {
try {
ThreadStateDemo.class.wait(); // 会一直等
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "t-waiting");
tWaiting.start();
Thread.sleep(800);
printThreadInfo(tWaiting, "WAITING – Object.wait()");
// 5. TIMED_WAITING(几种常见形式)
Thread tTimed = new Thread(() -> {
try {
Thread.sleep(15000); // 最简单的一种
// 或者: LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(30));
// 或者: synchronized后 wait(15000)
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}, "t-timed-waiting");
tTimed.start();
Thread.sleep(800);
printThreadInfo(tTimed, "TIMED_WAITING – Thread.sleep()");
// 6. 让程序不要马上退出
System.out.println("\\n所有演示线程已启动。pid = " + ProcessHandle.current().pid());
System.out.println("请在新终端运行以下命令观察(大约10秒内):");
System.out.println(" jstack " + ProcessHandle.current().pid());
System.out.println(" top -H -p " + ProcessHandle.current().pid());
System.out.println(" ps -eLo pid,lwp,stat,comm | grep t-");
System.out.println(" cat /proc/" + ProcessHandle.current().pid() + "/task/[LWP]/stat # 看第3列状态字母");
System.out.println("\\n按回车退出…");
System.in.read();
}
private static void printThreadInfo(Thread t, String msg) {
System.out.printf("%-25s : %-10s (java state)%n", msg, t.getState());
}
}


网硕互联帮助中心



评论前必须登录!
注册