第六章:多线程与并发
6.2 线程的生命周期与管理
线程的生命周期
在Java中,线程的生命周期可以分为以下几个状态:
新建(New)
- 线程对象被创建,但尚未调用
start()方法。 - 此时线程还未开始执行。
- 线程对象被创建,但尚未调用
就绪(Runnable)
- 调用
start()方法后,线程进入就绪状态。 - 线程等待CPU调度,一旦获得CPU时间片,线程开始执行。
- 调用
运行(Running)
- 线程获得CPU资源,执行
run()方法中的代码。 - 线程可能因为时间片用完或主动让出CPU而重新进入就绪状态。
- 线程获得CPU资源,执行
阻塞(Blocked)
- 线程因为某些原因(如等待I/O操作、获取锁失败等)暂时停止执行。
- 阻塞状态解除后,线程重新进入就绪状态。
等待(Waiting)
- 线程调用
wait()、join()或LockSupport.park()方法进入等待状态。 - 需要其他线程显式唤醒(如
notify()、notifyAll()或LockSupport.unpark())。
- 线程调用
超时等待(Timed Waiting)
- 线程调用带有超时参数的方法(如
sleep(long millis)、wait(long timeout)等)。 - 超时时间到达后,线程自动恢复。
- 线程调用带有超时参数的方法(如
终止(Terminated)
- 线程执行完
run()方法或因为异常退出。 - 线程生命周期结束,无法再次启动。
- 线程执行完
线程状态转换图
New → Runnable ↔ Running → Terminated
↓ ↑
Blocked/Waiting/Timed Waiting
线程管理
1. 线程的创建与启动
- 通过继承
Thread类或实现Runnable接口创建线程。 - 调用
start()方法启动线程,进入就绪状态。
2. 线程的暂停与恢复
- 使用
Thread.sleep(long millis)让线程进入超时等待状态。 - 使用
wait()和notify()实现线程间的协作。
3. 线程的中断
- 调用
interrupt()方法中断线程。 - 线程可以通过
isInterrupted()检查中断状态,或捕获InterruptedException处理中断。
4. 线程的终止
- 自然终止:
run()方法执行完毕。 - 强制终止:不推荐使用
stop()方法(已废弃),应通过标志位或中断机制优雅终止线程。
5. 线程优先级
- 通过
setPriority(int priority)设置线程优先级(1~10,默认5)。 - 优先级高的线程获得更多CPU时间片,但不保证绝对顺序。
6. 守护线程(Daemon Thread)
- 通过
setDaemon(true)将线程设置为守护线程。 - 当所有非守护线程结束时,守护线程会自动终止。
示例代码
public class ThreadLifecycleDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("线程开始执行...");
try {
Thread.sleep(1000); // 进入超时等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行结束。");
});
System.out.println("线程状态: " + thread.getState()); // NEW
thread.start();
System.out.println("线程状态: " + thread.getState()); // RUNNABLE
Thread.sleep(500);
System.out.println("线程状态: " + thread.getState()); // TIMED_WAITING
thread.join();
System.out.println("线程状态: " + thread.getState()); // TERMINATED
}
}
总结
- 理解线程的生命周期是编写高效并发程序的基础。
- 合理管理线程状态可以避免死锁、资源竞争等问题。
- 推荐使用
java.util.concurrent包中的工具类简化线程管理。
