Java 线程生命周期是指线程从创建到终止的整个过程。一个线程的生命周期可以分为多个状态,每个状态之间可以根据特定事件进行转换。以下是线程生命周期的详细介绍:
1. 线程的状态
Java 中线程的状态主要有以下几种:
新建 (New):线程被创建后,处于新建状态。在这个状态下,线程对象已经被创建,但是尚未开始执行。
Runnable (就绪):线程在新建状态后调用
start()
方法进入 Runnable 状态。这个状态表示线程已经准备好运行,但并不一定正在运行;它可能会因为 CPU 的调度而被挂起。Runnable 状态实际上包括了所有准备要执行以及正在执行的线程。Blocked (阻塞):当一个线程试图获取一个已经被其他线程持有的对象锁时,它会进入阻塞状态。此时,该线程无法继续执行,直到获得该锁。
Waiting (等待):处于等待状态的线程是在等待某个条件的发生,通常是通过调用
Object.wait()
、Thread.join()
或LockSupport.park()
等方法。线程在这个状态不能被调度。Timed Waiting (计时等待):与等待状态类似,但在计时等待状态下,线程在一定的时间后会自动返回 Runnable 状态。常见的调用方法包括
Thread.sleep(millis)
、Object.wait(millis)
、Thread.join(millis)
和LockSupport.parkNanos()
。Terminated (死亡):线程完成执行或由于异常结束后进入终止状态。在这个状态下,线程对象仍然存在,但无法重新启动。
2. 状态转换过程
以下是线程在不同状态之间的转换过程:
- 新建到 Runnable:线程通过调用
start()
方法转换为 Runnable 状态。 - Runnable 到 Running:当线程获得 CPU 时间片时,转换为 Running 状态。
- Running 到 Blocked:如果线程试图获取一个被其他线程持有的锁,它将进入 Blocked 状态。
- Running 到 Waiting:当线程调用
Object.wait()
、Thread.join()
等方法后,将进入 Waiting 状态。 - Running 到 Timed Waiting:调用
Thread.sleep(millis)
或Object.wait(millis)
后,将进入 Timed Waiting 状态。 - Waiting 到 Runnable:当满足条件后(如调用
notify()
或notifyAll()
),线程将转回 Runnable 状态。 - Blocked 到 Runnable:当持有锁的线程释放锁后,阻塞的线程将转换为 Runnable 状态。
- 任何状态到 Terminated:当线程的
run()
方法执行完毕或抛出未捕获的异常时,线程进入 Terminated 状态。
3. 线程状态图
以下是 Java 线程状态的简化状态图示意:
+-------+
| New |-----> +--------+
+-------+ | Runnable|
+--------+
| ^
v |
+-----------+
| Running |
+-----------+
| | |
+---+ | | |
| | | | |
v v | | |
+--------+ +--------+
| Blocked | | Waiting |
+--------+ +--------+
^ ^
| |
+----------------+
4. 例子
下面的代码片段展示了如何创建一个线程,以及它的生命周期中的状态转换:
class MyThread extends Thread {
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " is running.");
Thread.sleep(1000); // Timed Waiting 状态
System.out.println(Thread.currentThread().getName() + " is resumed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadLifecycleExample {
public static void main(String[] args) {
MyThread thread = new MyThread(); // New 状态
thread.start(); // 变为 Runnable 状态
}
}
5. 总结
理解 Java 线程的生命周期对于开发并发程序非常重要。线程的状态决定了线程的执行行为和调度策略,对于实现复杂的多线程应用至关重要。合理使用线程的状态转换,有助于提高程序的性能和响应能力。