在 Java 中,线程的生命周期定义了线程从创建到终止所经历的不同状态。这些状态由 Thread.State
枚举类型表示,具体包括以下几种:
1. 新建(New)
当一个 Thread
对象被创建时,就进入了新建状态。此时,线程还未启动,即还没有调用 start()
方法。
Thread thread = new Thread(() -> {
// 线程执行的代码
});
// 此时线程处于 NEW 状态
2. 可运行(Runnable)
一旦调用了线程对象的 start()
方法,线程就进入了可运行状态。这意味着线程现在可以由 Java 虚拟机调度执行,但它不一定正在运行;它可能正在等待 CPU 时间片来开始执行。
thread.start(); // 线程进入 RUNNABLE 状态
3. 阻塞(Blocked)
当一个线程试图获取另一个线程持有的锁而无法获得时,它就会进入阻塞状态。例如,在尝试进入同步块或方法时,如果该同步块或方法已经被其他线程占用,当前线程就会被阻塞,直到获取到锁为止。
4. 等待(Waiting)
一个线程可以通过几种方式进入等待状态:
- 调用没有超时参数的
Object.wait()
方法。 - 调用
Thread.join()
方法等待另一个线程完成。 - 调用
LockSupport.park()
方法。
处于等待状态的线程必须被其他线程显式地唤醒(例如通过 notify()
或 notifyAll()
方法)才能重新回到可运行状态。
5. 定时等待(Timed Waiting)
与等待状态类似,但这种状态下线程有一个最大等待时间限制。常见的导致线程进入定时等待状态的方法有:
Thread.sleep(long millis)
:使当前线程暂停指定的时间。Object.wait(long timeout)
:带有超时参数的等待方法。Thread.join(long millis)
:等待另一个线程完成,但最多等待指定的时间。LockSupport.parkNanos(Object blocker, long nanos)
和LockSupport.parkUntil(long deadline)
。
6. 终止(Terminated)
线程完成了它的执行或者因为异常退出后就进入了终止状态。这可能是由于 run()
方法正常结束,或者是由于未捕获的异常导致线程停止执行。
try {
thread.join(); // 等待线程结束
} catch (InterruptedException e) {
e.printStackTrace();
}
// 此时线程已 TERMINATED
总结
Java 线程的生命周期可以通过下图简单概括:
NEW --(调用 start())--> RUNNABLE --(遇到 synchronized 块/方法需要锁)--> BLOCKED
RUNNABLE --(调用 wait(), join(), park())--> WAITING
RUNNABLE --(调用 sleep(), wait(timeout), join(timeout), parkNanos(), parkUntil())--> TIMED_WAITING
(RUNNABLE/WAITING/TIMED_WAITING) --(任务完成或异常)--> TERMINATED
理解线程的生命周期有助于更好地管理多线程程序中的资源和控制流程,确保程序的稳定性和效率。
THE END