Java 中线程的生命周期(状态)具体包含哪几种?
在 Java 中,线程的生命周期(状态)由 java.lang.Thread.State 枚举类明确规定。具体来说,Java 线程的生命周期包含以下 6 种 状态:
1. NEW(新建)
- 含义:线程对象已经被创建,但是还没有调用
start()方法。 - 说明:此时它只是一个普通的 Java 对象,操作系统中并没有真正的线程与之对应。
- 示例:
Thread t = new Thread();此时t就是 NEW 状态。
2. RUNNABLE(可运行)
- 含义:线程在 Java 虚拟机(JVM)中执行的状态。
- 注意:Java 中的
RUNNABLE状态包含了操作系统层面的就绪态(Ready)和运行态(Running)。- 就绪(Ready):线程已经准备好运行,正在等待获取 CPU 时间片。
- 运行(Running):线程已经获取到 CPU 时间片,正在执行代码。
- Java 并没有区分这两种状态,统一称为 RUNNABLE。
- 转换:调用
t.start()方法后,线程从 NEW 进入 RUNNABLE 状态。
3. BLOCKED(阻塞)
- 含义:线程正在等待获取一个监视器锁(Monitor Lock),以便进入一个
synchronized块或方法,或者在调用Object.wait()后被唤醒时重新进入synchronized块。 - 说明:BLOCKED 状态仅仅与
synchronized关键字相关。如果使用java.util.concurrent.locks包下的锁(如ReentrantLock),线程等待锁时是处于WAITING或TIMED_WAITING状态,而不是BLOCKED。
4. WAITING(无限期等待)
- 含义:线程进入无限期等待状态,它在等待另一个线程执行特定的操作(如唤醒或中断)。处于该状态的线程不会被分配 CPU 时间片。
- 触发条件(调用以下无超时参数的方法):
Object.wait():等待其他线程调用notify()或notifyAll()。Thread.join():等待指定的线程执行完毕(终止)。LockSupport.park():等待其他线程调用LockSupport.unpark()。
5. TIMED_WAITING(限期等待)
- 含义:与 WAITING 类似,但它有最大等待时间。在这个时间内,如果没有被唤醒,系统会自动唤醒它。处于该状态的线程也不会被分配 CPU 时间片。
- 触发条件(调用以下带有超时参数的方法):
Thread.sleep(long millis)Object.wait(long timeout)Thread.join(long millis)LockSupport.parkNanos()LockSupport.parkUntil()
6. TERMINATED(终止)
- 含义:线程已经执行完毕,生命周期结束。
- 触发条件:
- 线程的
run()方法正常执行结束。 - 线程在执行过程中抛出了未捕获的异常(Exception)或错误(Error)导致意外结束。
- 线程的
- 注意:一旦线程进入 TERMINATED 状态,就不能再调用
start()方法重新启动,否则会抛出IllegalThreadStateException。
💡 核心状态转换关系总结
为了更好地理解,可以参考以下状态转换逻辑:
- NEW -> RUNNABLE:调用
start()。 - RUNNABLE -> BLOCKED:尝试获取
synchronized锁失败。 - BLOCKED -> RUNNABLE:成功获取到了
synchronized锁。 - RUNNABLE -> WAITING / TIMED_WAITING:调用
wait(),sleep(),join(),park()等方法。 - WAITING / TIMED_WAITING -> RUNNABLE:时间到期、被
notify/notifyAll唤醒、被中断、或者unpark()。(注意:如果是wait()被唤醒,且没有获取到锁,会先进入 BLOCKED 状态)。 - RUNNABLE -> TERMINATED:
run()方法执行完毕或异常退出。
⚠️ 面试常考辨析
sleep()和wait()的区别?sleep()是Thread类的静态方法,进入TIMED_WAITING状态,不会释放锁。wait()是Object类的方法,进入WAITING/TIMED_WAITING状态,必须在同步块中调用,并且会释放锁。
- BLOCKED 和 WAITING 的区别?
- BLOCKED 是被动的,因为竞争
synchronized锁失败而进入。 - WAITING 是主动的,因为代码中调用了
wait()、join()、park()等方法主动交出执行权。
- BLOCKED 是被动的,因为竞争
右滑查看面试常问