在 Java 中,线程的生命周期可以分为多个状态,这些状态描述了线程从创建到终止的整个过程。Java 线程的生命周期主要包括以下七大状态:
1.新建状态(New)
当一个线程对象被创建但尚未调用 start()
方法时,线程处于新建状态。此时,线程还没有开始执行。
2.可运行状态(Ready)
当调用 start()
方法后,线程进入可运行状态。在这个状态下,线程可能正在运行,也可能在等待操作系统分配 CPU 时间片。
3.运行状态(Running)
当线程获得 CPU 时间片并开始执行时,线程进入运行状态。在这个状态下,线程正在执行其任务。
4.阻塞状态(Blocked)
当线程由于某些原因(如等待 I/O 操作完成、等待获取锁等)暂时无法继续执行时,线程进入阻塞状态。在这个状态下,线程不会占用 CPU 资源。
5.等待状态(Waiting)
当线程调用 Object.wait()
、Thread.join()
或 LockSupport.park()
等方法时,线程进入等待状态。在这个状态下,线程等待其他线程显式地唤醒。
6.计时等待状态(Timed Waiting)
当线程调用带有超时参数的方法(如 Thread.sleep(long)
、Object.wait(long)
、Thread.join(long)
或 LockSupport.parkNanos(long)
)时,线程进入计时等待状态。在这个状态下,线程等待一段时间后自动恢复。
7.终止状态(Terminated)
当线程完成其任务或因异常而终止时,线程进入终止状态。在这个状态下,线程不再执行,并且无法再次启动。
Runnable 状态的细分
在 Java 官方文档中,实际上是6个状态,Runnable 状态实际上包含了两个子状态:
- 就绪状态(Ready):线程已经准备好运行,等待操作系统调度。
- 运行状态(Running):线程正在执行其任务,占用 CPU 时间片。
区别
就绪状态(Ready):
- 线程已经调用了
start()
方法,但尚未获得 CPU 时间片。- 线程在就绪队列中等待操作系统调度。
- 线程在就绪状态下不会执行任何代码。
运行状态(Running):
- 线程获得了 CPU 时间片,正在执行其任务。
- 线程在运行状态下会执行其
run()
方法中的代码。- 线程在运行状态下可能会因为时间片用完而被操作系统暂停,重新回到就绪状态
java
public class ThreadLifecycleExample {
public static void main(String[] args) {
// 新建状态
Thread thread = new Thread(() -> {
System.out.println("线程正在运行...");
try {
// 计时等待状态
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程运行结束。");
});
// 可运行状态
thread.start();
// 主线程等待子线程完成
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 终止状态
System.out.println("子线程已终止。");
}
}
注意事项
- 线程调度:操作系统负责线程的调度,具体何时从就绪状态切换到运行状态由操作系统决定。
- 状态转换:线程在运行过程中可能会在就绪状态和运行状态之间多次切换,这取决于操作系统的调度策略和线程的优先级。
- 并发性:多个线程可能在同一时间处于就绪状态,等待操作系统调度执行。
- 性能考虑:在设计多线程程序时,需要考虑线程的状态转换对性能的影响,避免频繁的状态切换和线程阻塞。