Java 线程状态详解
Java 线程的六种状态描述了线程从创建到终止的完整生命周期,理解状态转换是掌握多线程的基础。
一、六种线程状态
public enum State {
NEW, // 新建
RUNNABLE, // 运行
BLOCKED, // 阻塞
WAITING, // 等待
TIMED_WAITING, // 超时等待
TERMINATED // 终止
}
状态转换图

二、状态详解
2.1 NEW(新建状态)
线程对象已创建,但尚未调用 start() 方法:
Thread thread = new Thread(() -> {
System.out.println("Running");
});
// 此时 thread.getState() == State.NEW
2.2 RUNNABLE(运行状态)
包含两种情况:
- 就绪(Ready):等待 CPU 调度
- 运行中(Running):正在 CPU 上执行
thread.start();
// 此时 thread.getState() == State.RUNNABLE
2.3 BLOCKED(阻塞状态)
线程因竞争同步锁失败而暂停:
// 线程 A 持有锁
synchronized (lock) {
// 线程 B 尝试获取锁 → BLOCKED
}
转换条件:
- → BLOCKED:竞争
synchronized锁失败 - → RUNNABLE:获取到锁
2.4 WAITING(等待状态)
无限期等待,需其他线程显式唤醒:
// 方式 1:Object.wait()
synchronized (obj) {
obj.wait();
}
// 方式 2:Thread.join()
thread.join();
// 方式 3:LockSupport.park()
LockSupport.park();
唤醒方式:
Object.notify()/notifyAll()Thread.interrupt()LockSupport.unpark()
2.5 TIMED_WAITING(超时等待)
有限期等待,超时后自动唤醒:
// 方式 1:Thread.sleep(time)
Thread.sleep(1000);
// 方式 2:Object.wait(time)
synchronized (obj) {
obj.wait(1000);
}
// 方式 3:Thread.join(time)
thread.join(1000);
// 方式 4:LockSupport.parkNanos(time)
LockSupport.parkNanos(1000_000_000L);
2.6 TERMINATED(终止状态)
线程执行完毕或因异常退出:
thread.run(); // 执行完毕
// 此时 thread.getState() == State.TERMINATED
三、状态转换实战
3.1 BLOCKED → RUNNABLE
Object lock = new Object();
// 线程 A
new Thread(() -> {
synchronized (lock) {
Thread.sleep(2000); // 持有锁 2 秒
}
}).start();
// 线程 B
new Thread(() -> {
synchronized (lock) { // 竞争锁失败 → BLOCKED
System.out.println("Got lock"); // 获取锁 → RUNNABLE
}
}).start();
3.2 yield() vs sleep()
| 方法 | 作用 | 状态变化 | 锁释放 |
|---|---|---|---|
| yield() | 让出 CPU 时间片 | RUNNABLE → RUNNABLE | 不释放 |
| sleep() | 暂停指定时间 | RUNNABLE → TIMED_WAITING | 不释放 |
// yield() - 让出 CPU,但仍可被调度
Thread.yield();
// sleep() - 暂停 1 秒
Thread.sleep(1000);
四、常见问题
4.1 如何查看线程状态?
Thread thread = new Thread(() -> {
// ...
});
// 方式 1:getState()
System.out.println(thread.getState());
// 方式 2:jstack(命令行)
jstack <pid>
// 方式 3:VisualVM(图形化)
4.2 死锁检测
// 死锁:两个线程互相等待对方的锁
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] deadlockedThreads = bean.findDeadlockedThreads();
if (deadlockedThreads != null) {
System.out.println("检测到死锁!");
}
4.3 如何避免死锁?
- 固定顺序:所有线程按相同顺序获取锁
- 超时机制:使用
tryLock(timeout) - 死锁检测:定期检测并恢复
五、总结
线程状态核心要点:
| 状态 | 触发条件 | 唤醒方式 |
|---|---|---|
| NEW | 创建线程对象 | start() |
| RUNNABLE | 就绪/运行中 | CPU 调度 |
| BLOCKED | 竞争锁失败 | 获取锁 |
| WAITING | wait()/join()/park() | notify()/unpark() |
| TIMED_WAITING | sleep()/wait(time) | 超时/唤醒 |
| TERMINATED | run() 结束 | - |
理解线程状态转换是解决并发问题的基础,建议结合 jstack 等工具实际观察。