在Java中,线程的状态由
java.lang.Thread.State
枚举定义每个线程在其生命周期内会经历不同的状态,并且这些状态之间可以相互转换
1. 线程的六种状态
根据 Thread.State
枚举,Java线程有以下六种状态:
(1) NEW(新建)
-
描述:线程对象已经被创建,但尚未调用
start()
方法启动 -
特点:
- 线程尚未开始运行
- 此时线程处于初始状态
-
示例:
Thread thread = new Thread(() -> System.out.println("Hello")); // 当前线程状态为 NEW
(2) RUNNABLE(可运行)
-
描述:线程已经启动,正在 JVM 中执行,或者正在等待操作系统的资源(如CPU时间片)
-
特点:
- 线程可能正在运行,也可能在等待CPU调度
- 在操作系统层面,线程可能处于运行状态或就绪状态
-
转换条件:
- 调用
start()
方法后,线程从NEW
状态进入RUNNABLE
状态
- 调用
-
示例:
Thread thread = new Thread(() -> System.out.println("Running")); thread.start(); // 当前线程状态为 RUNNABLE
(3) BLOCKED(阻塞)
-
描述:线程在尝试获取一个被其他线程持有的锁时进入此状态
-
特点:
- 线程正在等待进入同步代码块或方法
- 一旦锁可用,线程将重新进入
RUNNABLE
状态
-
转换条件:
- 线程试图获取一个已被其他线程占用的锁
-
示例:
synchronized (lock) {// 如果另一个线程持有 lock,则当前线程进入 BLOCKED 状态 }
(4) WAITING(等待)
-
描述:线程在等待另一个线程显式地唤醒它
-
特点:
- 线程无限期等待,直到被其他线程唤醒
- 常见的触发方法包括:
Object.wait()
(无超时版本)Thread.join()
(无超时版本)LockSupport.park()
-
转换条件:
- 调用上述方法后,线程从
RUNNABLE
状态进入WAITING
状态 - 被其他线程唤醒后,线程重新进入
RUNNABLE
状态
- 调用上述方法后,线程从
-
示例:
Object lock = new Object(); synchronized (lock) {lock.wait(); // 当前线程进入 WAITING 状态 }
(5) TIMED_WAITING(计时等待)
-
描述:线程在等待一段时间后自动恢复,或者被其他线程显式唤醒
-
特点:
- 线程等待的时间是有限的。
- 常见的触发方法包括:
Thread.sleep(long millis)
Object.wait(long timeout)
Thread.join(long millis)
LockSupport.parkNanos()
LockSupport.parkUntil()
-
转换条件:
- 调用上述方法后,线程从
RUNNABLE
状态进入TIMED_WAITING
状态。 - 等待时间结束后,线程重新进入
RUNNABLE
状态。
- 调用上述方法后,线程从
-
示例:
Thread.sleep(1000); // 当前线程进入 TIMED_WAITING 状态,持续1秒
(6) TERMINATED(终止)
-
描述:线程已经完成执行,或者因异常而终止
-
特点:
- 线程的生命周期结束
- 此时线程对象仍然存在,但无法再次启动
-
转换条件:
- 线程的
run()
方法执行完毕 - 线程因未捕获的异常而终止
- 线程的
-
示例:
Thread thread = new Thread(() -> System.out.println("Done")); thread.start(); thread.join(); // 等待线程结束 // 当前线程状态为 TERMINATED
2. 线程状态的转换图
以下是 Java 线程状态之间的转换关系:
start()
NEW --------------> RUNNABLE <-----------------------+| ^ || | || sleep() || | || v || TIMED_WAITING || | || +-------------------+| || wait()/join()| || v| WAITING| || +-------------------+| | || 获取锁 | || v || BLOCKED -------------> RUNNABLE -----------> TERMINATED^ ^| |run()结束/异常 |
3. 状态转换详解
(1) NEW → RUNNABLE
- 调用
start()
方法后,线程从NEW
状态进入RUNNABLE
状态 - 注意:直接调用
run()
方法不会启动新线程,而是作为普通方法在当前线程中执行
(2) RUNNABLE ↔ BLOCKED
- 当线程尝试进入同步代码块或方法,但锁被其他线程占用时,线程进入
BLOCKED
状态 - 一旦锁可用,线程重新进入
RUNNABLE
状态
(3) RUNNABLE ↔ WAITING
- 调用
wait()
、join()
或park()
方法后,线程进入WAITING
状态。 - 被其他线程显式唤醒(如调用
notify()
或unpark()
)后,线程重新进入RUNNABLE
状态。
(4) RUNNABLE ↔ TIMED_WAITING
- 调用
sleep()
、wait(long timeout)
或join(long millis)
方法后,线程进入TIMED_WAITING
状态 - 等待时间结束后,线程重新进入
RUNNABLE
状态
(5) RUNNABLE → TERMINATED
- 线程的
run()
方法执行完毕,或者因未捕获的异常而终止,线程进入TERMINATED
状态
4. 总结
状态 | 描述 | 典型方法 |
---|---|---|
NEW | 线程对象已创建,但尚未启动 | new Thread() |
RUNNABLE | 线程正在运行或等待CPU调度 | start() |
BLOCKED | 线程等待获取锁 | synchronized |
WAITING | 线程无限期等待另一个线程唤醒 | wait() 、join() 、park() |
TIMED_WAITING | 线程等待一段时间后自动恢复或被唤醒 | sleep() 、wait(long) 、join(long) |
TERMINATED | 线程执行完毕或因异常终止 | run() 结束 |