java状态如何转换
Java线程状态的转换
Java线程在其生命周期中会经历多种状态,这些状态之间的转换遵循特定的规则。Java线程的状态定义在java.lang.Thread.State枚举中,包括以下六种状态:
-
NEW(新建状态)
线程被创建但尚未调用start()方法。 -
RUNNABLE(可运行状态)
线程已启动,正在等待CPU时间片或正在运行。- 从
NEW状态调用start()方法后进入RUNNABLE状态。 - 线程在运行过程中可能因时间片用完或调度原因暂时回到
RUNNABLE状态。
- 从
-
BLOCKED(阻塞状态)
线程因等待获取锁而阻塞。- 当线程尝试进入
synchronized代码块或方法,但锁已被其他线程持有时进入BLOCKED状态。 - 锁释放后,线程重新进入
RUNNABLE状态。
- 当线程尝试进入
-
WAITING(等待状态)
线程因调用Object.wait()、Thread.join()或LockSupport.park()而进入无限期等待。- 需要其他线程调用
notify()、notifyAll()或LockSupport.unpark()来唤醒。 - 唤醒后进入
RUNNABLE状态。
- 需要其他线程调用
-
TIMED_WAITING(超时等待状态)
线程因调用Thread.sleep(long)、Object.wait(long)或Thread.join(long)等带有超时参数的方法进入限时等待。- 超时时间到达或收到唤醒信号后进入
RUNNABLE状态。
- 超时时间到达或收到唤醒信号后进入
-
TERMINATED(终止状态)
线程执行完run()方法或因异常退出后进入终止状态。
状态转换示例代码
public class ThreadStateDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000); // TIMED_WAITING
synchronized (ThreadStateDemo.class) {
ThreadStateDemo.class.wait(); // WAITING
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(thread.getState()); // NEW
thread.start();
System.out.println(thread.getState()); // RUNNABLE
Thread.sleep(500);
System.out.println(thread.getState()); // TIMED_WAITING
Thread.sleep(1000);
synchronized (ThreadStateDemo.class) {
System.out.println(thread.getState()); // WAITING
ThreadStateDemo.class.notify();
}
thread.join();
System.out.println(thread.getState()); // TERMINATED
}
}
关键转换规则
NEW→RUNNABLE:调用start()方法。RUNNABLE→BLOCKED:竞争锁失败。RUNNABLE→WAITING/TIMED_WAITING:调用等待或睡眠方法。WAITING/TIMED_WAITING→RUNNABLE:被唤醒或超时。RUNNABLE→TERMINATED:线程执行完毕或抛出未捕获异常。
注意:BLOCKED状态仅与同步锁竞争相关,而WAITING和TIMED_WAITING通常由显式的线程协作方法触发。






