Java 线程的生命周期可以分为以下几个主要阶段,每个阶段代表了线程从创建到终止的不同状态。理解这些状态及其转换对于编写健壮的多线程应用程序非常重要。
线程的生命周期状态
- 新建 (New):当线程对象被创建,但还没有调用
start()
方法时,线程处于新建状态。 - 就绪 (Runnable):当调用
start()
方法后,线程进入就绪状态,等待被线程调度器选中执行。此状态下,线程可能正在运行,也可能等待操作系统分配处理器时间。 - 运行 (Running):线程调度器从就绪线程池中选中线程开始执行时,线程处于运行状态。
- 阻塞 (Blocked):线程等待某个监视器锁定 (lock) 时,进入阻塞状态。通常是等待进入同步代码块或同步方法。
- 等待 (Waiting):线程等待其他线程显式唤醒 (wake-up),进入等待状态。调用
wait()
、join()
或LockSupport.park()
方法时,线程会进入此状态。 - 超时等待 (Timed Waiting):线程等待一定时间后自动唤醒,进入超时等待状态。调用
sleep()
、wait(long timeout)
、join(long timeout)
或LockSupport.parkNanos()
/LockSupport.parkUntil()
方法时,线程会进入此状态。 - 终止 (Terminated):线程执行完成或因异常退出时,进入终止状态。
线程状态转换示意图
+---------------------+ +---------------------+ +---------------------+
| New | -----> | Runnable | -----> | Running |
+---------------------+ +---------------------+ +---------------------+
| ^ |
| | |
| | |
v | v
+---------------------+ | +---------------------+
| Blocked | <----------------+ | Waiting |
+---------------------+ +---------------------+
^ ^ |
| | |
+--------------------------------------------------------------+ v
+---------------------+
| Timed Waiting |
+---------------------+
示例代码:线程生命周期
以下是一个简单的示例,展示了线程在不同状态之间的转换:
public class ThreadLifecycleDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("Thread state: " + Thread.currentThread().getState());
try {
// 线程进入等待状态
synchronized (ThreadLifecycleDemo.class) {
ThreadLifecycleDemo.class.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread state: " + Thread.currentThread().getState());
});
// 新建状态
System.out.println("Thread state after creation: " + thread.getState());
thread.start();
// 就绪状态
System.out.println("Thread state after calling start(): " + thread.getState());
Thread.sleep(100); // 确保线程进入等待状态
System.out.println("Thread state after entering waiting: " + thread.getState());
synchronized (ThreadLifecycleDemo.class) {
// 唤醒线程
ThreadLifecycleDemo.class.notify();
}
Thread.sleep(100); // 确保线程结束
// 终止状态
System.out.println("Thread state after completion: " + thread.getState());
}
}
详细说明各状态
- 新建 (New):线程对象创建后但未启动。
Thread thread = new Thread();
System.out.println(thread.getState()); // 输出:NEW
- 就绪 (Runnable):线程调用
start()
方法后,进入就绪状态。
thread.start();
System.out.println(thread.getState()); // 输出:RUNNABLE
-
运行 (Running):线程调度器选中线程执行时,进入运行状态。此状态不能通过
getState()
方法明确检测到,因为它仍然是RUNNABLE
状态的一部分。 -
阻塞 (Blocked):线程等待锁释放时,进入阻塞状态。
synchronized (lock) {
// 线程在此等待进入同步块
}
- 等待 (Waiting):线程无限期等待另一个线程唤醒。
synchronized (object) {
object.wait();
}
- 超时等待 (Timed Waiting):线程等待一段时间后自动唤醒。
Thread.sleep(1000); // 超时等待
synchronized (object) {
object.wait(1000); // 超时等待
}
- 终止 (Terminated):线程执行完成或因异常退出。
System.out.println(thread.getState()); // 输出:TERMINATED
总结
Java 线程的生命周期包含了从创建到终止的各个阶段,每个阶段都有其特定的状态和转换条件。理解这些状态及其转换有助于编写更加健壮和高效的多线程应用程序。