今日金句: "理解线程的生命周期,就是掌握并发编程的节奏。"
📚 课程概述
Day 3 深入探索 Java 线程的完整生命周期,掌握线程的六大状态及其转换条件,精通各种线程控制方法的使用,并通过实战代码理解中断机制、守护线程等核心概念。
🎯 学习目标
- 深入理解线程的六大状态及其转换条件
- 掌握线程控制方法:sleep、join、yield、interrupt
- 理解线程中断机制的正确处理方式
- 掌握守护线程的特性和应用场景
- 学会线程状态的监控和调试技巧
- 完成线程状态转换的实战练习
🧠 理论基础
1. 线程六大状态详解
1.1 线程状态概述
Java 线程的生命周期被明确定义为 6 种状态,这些状态定义在 java.lang.Thread.State 枚举中:
| 状态 | 说明 | 触发条件 | 是否可运行 |
|---|---|---|---|
| NEW | 新建状态 | 线程被创建但未启动 | ❌ |
| RUNNABLE | 可运行状态 | 调用 start() 后,包含 READY 和 RUNNING | ✅ |
| BLOCKED | 阻塞状态 | 等待获取监视器锁 | ❌ |
| WAITING | 等待状态 | 调用 wait()、join() 等 | ❌ |
| TIMED_WAITING | 计时等待 | 调用 sleep()、wait(timeout) 等 | ❌ |
| TERMINATED | 终止状态 | 线程执行完成或异常退出 | ❌ |
1.2 状态转换图
1.3 状态详细分析
NEW (新建状态)
// 线程被创建但未启动
Thread thread = new Thread(() -> {
System.out.println("线程执行");
});
// 此时线程状态为 NEW
System.out.println("State: " + thread.getState()); // NEW
RUNNABLE (可运行状态)
// 包含操作系统层面的 READY 和 RUNNING 状态
thread.start();
// 此时线程状态为 RUNNABLE
System.out.println("State: " + thread.getState()); // RUNNABLE
BLOCKED (阻塞状态)
// 等待获取监视器锁
synchronized (lock) {
// 持有锁的线程
Thread blocker = new Thread(() -> {
synchronized (lock) {
// 这里会阻塞,因为锁被主线程持有
}
});
blocker.start();
// blocker 状态为 BLOCKED
}
2. 线程控制方法深度解析
2.1 sleep() 方法详解
sleep() 是 Thread 类的静态方法,让当前线程休眠指定时间。
方法签名:
public static void sleep(long millis) throws InterruptedException
public static void sleep(long millis, int nanos) throws InterruptedException
核心特性:
- 静态方法:只影响当前执行的线程
- 不释放锁:休眠期间不会释放已持有的锁
- 可中断:其他线程可以中断休眠状态
- 精度限制:实际休眠时间可能超过指定时间
/**
* sleep() 方法深度演示
*/
public class SleepDeepDive {
private static final Object lock = new Object();
public static void main(String[] args) {
System.out.println("=== sleep() 方法深度演示 ===");
// 演示1:sleep 不释放锁
demonstrateSleepWithLock();
// 演示2:sleep 的中断响应
demonstrateSleepInterruption();
// 演示3:sleep 精度测试
demonstrateSleepPrecision();
}
// 演示1:sleep 不释放锁
private static void demonstrateSleepWithLock() {
System.out.println("\n--- 演示1:sleep 不释放锁 ---");
Thread sleepingThread = new Thread(() -> {
synchronized (lock) {
System.out.println("休眠线程获取锁,开始休眠...");
try {
Thread.sleep(2000); // 休眠但不释放锁
} catch (InterruptedException e) {
System.out.println("休眠被中断");
Thread.currentThread().interrupt();
}
System.out.println("休眠线程醒来,准备释放锁");
}
}, "Sleeping-Thread");
Thread waitingThread = new Thread(() -> {
System.out.println("等待线程尝试获取锁...");
synchronized (lock) {
System.out.println("等待线程获取锁成功");
}
}, "Waiting-Thread");
sleepingThread.start();
// 稍微延迟后启动等待线程
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
waitingThread.start();
// 等待两个线程完成
try {
sleepingThread.join();
waitingThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示2:sleep 的中断响应
private static void demonstrateSleepInterruption() {
System.out.println("\n--- 演示2:sleep 的中断响应 ---");
Thread longSleepingThread = new Thread(() -> {
try {
System.out.println("长时间休眠线程开始休眠 5 秒...");
Thread.sleep(5000);
System.out.println("长时间休眠线程自然醒来");
} catch (InterruptedException e) {
System.out.println("长时间休眠线程被中断!");
// 重要:恢复中断状态
Thread.currentThread().interrupt();
}
}, "Long-Sleeping-Thread");
longSleepingThread.start();
// 主线程等待1秒后中断休眠线程
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断长时间休眠线程");
longSleepingThread.interrupt();
try {
longSleepingThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示3:sleep 精度测试
private static void demonstrateSleepPrecision() {
System.out.println("\n--- 演示3:sleep 精度测试 ---");
for (int i = 0; i < 5; i++) {
long startTime = System.nanoTime();
try {
Thread.sleep(10); // 休眠 10 毫秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
long endTime = System.nanoTime();
long actualSleep = (endTime - startTime) / 1_000_000; // 转换为毫秒
System.out.printf("计划休眠: 10ms, 实际休眠: %dms, 误差: %dms%n",
actualSleep, actualSleep - 10);
}
}
}
2.2 join() 方法详解
join() 方法让一个线程等待另一个线程完成执行。
方法签名:
public final void join() throws InterruptedException
public final void join(long millis) throws InterruptedException
public final void join(long millis, int nanos) throws InterruptedException
核心特性:
- 实例方法:作用在具体的线程对象上
- 释放锁:join() 过程中会释放锁
- 可中断:等待期间可以被其他线程中断
- 超时机制:支持设置最大等待时间
/**
* join() 方法深度演示
*/
public class JoinDeepDive {
public static void main(String[] args) {
System.out.println("=== join() 方法深度演示 ===");
// 演示1:基本 join 使用
demonstrateBasicJoin();
// 演示2:带超时的 join
demonstrateTimedJoin();
// 演示3:join 的中断处理
demonstrateJoinInterruption();
// 演示4:join 在复杂场景中的应用
demonstrateComplexJoinScenario();
}
// 演示1:基本 join 使用
private static void demonstrateBasicJoin() {
System.out.println("\n--- 演示1:基本 join 使用 ---");
Thread worker = new Thread(() -> {
System.out.println("工作线程开始执行...");
try {
Thread.sleep(2000); // 模拟耗时工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("工作线程执行完成");
}, "Worker-Thread");
System.out.println("主线程启动工作线程");
worker.start();
System.out.println("主线程等待工作线程完成...");
try {
worker.join(); // 等待工作线程完成
} catch (InterruptedException e) {
System.out.println("主线程等待被中断");
Thread.currentThread().interrupt();
}
System.out.println("主线程继续执行");
}
// 演示2:带超时的 join
private static void demonstrateTimedJoin() {
System.out.println("\n--- 演示2:带超时的 join ---");
Thread longRunningTask = new Thread(() -> {
System.out.println("长时间任务开始执行...");
try {
Thread.sleep(5000); // 执行 5 秒
} catch (InterruptedException e) {
System.out.println("长时间任务被中断");
Thread.currentThread().interrupt();
}
System.out.println("长时间任务执行完成");
}, "Long-Running-Task");
longRunningTask.start();
System.out.println("主线程等待长时间任务最多 2 秒...");
try {
long startTime = System.currentTimeMillis();
longRunningTask.join(2000); // 最多等待 2 秒
long endTime = System.currentTimeMillis();
long waitTime = endTime - startTime;
if (longRunningTask.isAlive()) {
System.out.println("任务在 2 秒内未完成,主线程继续执行 (实际等待: " + waitTime + "ms)");
} else {
System.out.println("任务在 2 秒内完成 (实际等待: " + waitTime + "ms)");
}
} catch (InterruptedException e) {
System.out.println("主线程等待被中断");
Thread.currentThread().interrupt();
}
}
// 演示3:join 的中断处理
private static void demonstrateJoinInterruption() {
System.out.println("\n--- 演示3:join 的中断处理 ---");
Thread slowTask = new Thread(() -> {
System.out.println("慢任务开始执行...");
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(500);
System.out.println("慢任务进度: " + (i + 1) + "/10");
}
} catch (InterruptedException e) {
System.out.println("慢任务被中断");
Thread.currentThread().interrupt();
}
}, "Slow-Task");
Thread waiter = new Thread(() -> {
System.out.println("等待线程开始等待慢任务...");
try {
slowTask.join(); // 等待慢任务完成
System.out.println("等待线程:慢任务已完成");
} catch (InterruptedException e) {
System.out.println("等待线程:等待过程被中断");
Thread.currentThread().interrupt();
}
}, "Waiter-Thread");
slowTask.start();
waiter.start();
// 主线程等待1秒后中断等待线程
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断等待线程");
waiter.interrupt();
try {
waiter.join();
slowTask.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示4:join 在复杂场景中的应用
private static void demonstrateComplexJoinScenario() {
System.out.println("\n--- 演示4:复杂 join 场景 ---");
// 创建多个工作线程
Thread[] workers = new Thread[3];
for (int i = 0; i < workers.length; i++) {
final int workerId = i;
workers[i] = new Thread(() -> {
System.out.println("工作线程 " + workerId + " 开始执行");
try {
Thread.sleep(1000 + workerId * 500); // 不同的执行时间
} catch (InterruptedException e) {
System.out.println("工作线程 " + workerId + " 被中断");
Thread.currentThread().interrupt();
}
System.out.println("工作线程 " + workerId + " 执行完成");
}, "Worker-" + workerId);
}
// 启动所有工作线程
for (Thread worker : workers) {
worker.start();
}
// 等待所有工作线程完成
System.out.println("主线程等待所有工作线程完成...");
for (Thread worker : workers) {
try {
worker.join();
System.out.println(worker.getName() + " 已完成");
} catch (InterruptedException e) {
System.out.println("等待 " + worker.getName() + " 时被中断");
Thread.currentThread().interrupt();
}
}
System.out.println("所有工作线程已完成,主线程继续执行");
}
}
2.3 yield() 方法详解
yield() 是一个静态方法,提示线程调度器当前线程愿意放弃 CPU 时间片。
方法签名:
public static void yield()
核心特性:
- 静态方法:只影响当前线程
- 只是建议:不保证立即生效
- 不释放锁:不会释放已持有的锁
- 状态不变:线程仍处于 RUNNABLE 状态
/**
* yield() 方法深度演示
*/
public class YieldDeepDive {
public static void main(String[] args) {
System.out.println("=== yield() 方法深度演示 ===");
// 演示1:yield 的基本效果
demonstrateBasicYield();
// 演示2:yield 在不同优先级线程中的效果
demonstrateYieldWithPriorities();
// 演示3:yield vs sleep 的区别
demonstrateYieldVsSleep();
}
// 演示1:yield 的基本效果
private static void demonstrateBasicYield() {
System.out.println("\n--- 演示1:yield 的基本效果 ---");
Thread yieldingThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("Yield线程: " + i);
if (i == 4) {
System.out.println("Yield线程执行 yield()");
Thread.yield(); // 礼让CPU
}
}
}, "Yield-Thread");
Thread normalThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("普通线程: " + i);
}
}, "Normal-Thread");
yieldingThread.start();
normalThread.start();
try {
yieldingThread.join();
normalThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示2:yield 在不同优先级线程中的效果
private static void demonstrateYieldWithPriorities() {
System.out.println("\n--- 演示2:yield 在不同优先级线程中的效果 ---");
Thread highPriorityThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("高优先级线程执行: " + i);
if (i == 2) {
System.out.println("高优先级线程执行 yield()");
Thread.yield();
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "High-Priority-Thread");
Thread lowPriorityThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("低优先级线程执行: " + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Low-Priority-Thread");
// 设置不同的优先级
highPriorityThread.setPriority(Thread.MAX_PRIORITY);
lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
lowPriorityThread.start();
highPriorityThread.start();
try {
highPriorityThread.join();
lowPriorityThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示3:yield vs sleep 的区别
private static void demonstrateYieldVsSleep() {
System.out.println("\n--- 演示3:yield vs sleep 的区别 ---");
Thread yieldThread = new Thread(() -> {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
System.out.println("Yield线程: " + i + ", 时间: " +
(System.currentTimeMillis() - startTime) + "ms");
Thread.yield(); // 立即返回
}
}, "Yield-Thread");
Thread sleepThread = new Thread(() -> {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
System.out.println("Sleep线程: " + i + ", 时间: " +
(System.currentTimeMillis() - startTime) + "ms");
try {
Thread.sleep(0); // 至少休眠1毫秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Sleep-Thread");
yieldThread.start();
sleepThread.start();
try {
yieldThread.join();
sleepThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("yield 只是建议,不保证立即生效");
System.out.println("sleep(0) 至少休眠1毫秒,保证线程切换");
}
}
2.4 interrupt() 中断机制详解
Java 的中断机制是一种协作机制,一个线程不能强制终止另一个线程,只能请求中断。
核心方法:
public void interrupt() // 设置中断标志
public boolean isInterrupted() // 检查中断标志(不清除)
public static boolean interrupted() // 检查并清除中断标志
中断响应规则:
- 如果线程处于
RUNNABLE状态:设置中断标志,线程自行检查 - 如果线程处于
BLOCKED或WAITING状态:抛出InterruptedException,清除中断标志 - 如果线程处于
TIMED_WAITING状态:抛出InterruptedException,清除中断标志
/**
* interrupt() 中断机制深度演示
*/
public class InterruptDeepDive {
public static void main(String[] args) {
System.out.println("=== interrupt() 中断机制深度演示 ===");
// 演示1:中断正常运行中的线程
demonstrateInterruptRunningThread();
// 演示2:中断阻塞状态中的线程
demonstrateInterruptBlockedThread();
// 演示3:中断等待状态中的线程
demonstrateInterruptWaitingThread();
// 演示4:优雅的中断处理模式
demonstrateGracefulInterruption();
// 演示5:中断标志的维护
demonstrateInterruptionFlag();
}
// 演示1:中断正常运行中的线程
private static void demonstrateInterruptRunningThread() {
System.out.println("\n--- 演示1:中断正常运行中的线程 ---");
Thread runningThread = new Thread(() -> {
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
count++;
System.out.println("运行中线程执行次数: " + count);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("运行中线程收到中断信号");
// 重新设置中断标志,让循环条件能检测到
Thread.currentThread().interrupt();
break;
}
}
System.out.println("运行中线程退出,中断状态: " +
Thread.currentThread().isInterrupted());
}, "Running-Thread");
runningThread.start();
// 主线程等待1秒后中断
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断运行中线程");
runningThread.interrupt();
try {
runningThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示2:中断阻塞状态中的线程
private static void demonstrateInterruptBlockedThread() {
System.out.println("\n--- 演示2:中断阻塞状态中的线程 ---");
Object lock = new Object();
Thread holderThread = new Thread(() -> {
synchronized (lock) {
System.out.println("锁持有线程开始持有锁...");
try {
Thread.sleep(3000); // 持有锁3秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("锁持有线程释放锁");
}
}, "Lock-Holder");
Thread blockedThread = new Thread(() -> {
System.out.println("阻塞线程尝试获取锁...");
try {
synchronized (lock) {
System.out.println("阻塞线程获取锁成功");
}
} catch (Exception e) {
System.out.println("阻塞线程异常: " + e.getMessage());
}
}, "Blocked-Thread");
holderThread.start();
blockedThread.start();
// 等待阻塞线程进入阻塞状态
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断阻塞线程");
blockedThread.interrupt();
try {
holderThread.join();
blockedThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示3:中断等待状态中的线程
private static void demonstrateInterruptWaitingThread() {
System.out.println("\n--- 演示3:中断等待状态中的线程 ---");
Thread waitingThread = new Thread(() -> {
try {
System.out.println("等待线程开始等待...");
synchronized (InterruptDeepDive.class) {
InterruptDeepDive.class.wait(); // 进入WAITING状态
}
System.out.println("等待线程被唤醒");
} catch (InterruptedException e) {
System.out.println("等待线程等待期间被中断");
Thread.currentThread().interrupt();
}
}, "Waiting-Thread");
Thread notifierThread = new Thread(() -> {
try {
Thread.sleep(2000);
synchronized (InterruptDeepDive.class) {
InterruptDeepDive.class.notifyAll();
System.out.println("通知线程发送通知");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Notifier-Thread");
waitingThread.start();
notifierThread.start();
// 主线程等待1秒后中断等待线程
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断等待线程");
waitingThread.interrupt();
try {
waitingThread.join();
notifierThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示4:优雅的中断处理模式
private static void demonstrateGracefulInterruption() {
System.out.println("\n--- 演示4:优雅的中断处理模式 ---");
Thread gracefulThread = new Thread(() -> {
System.out.println("优雅线程开始执行任务...");
try {
// 模拟一系列任务
for (int i = 1; i <= 10; i++) {
// 检查中断状态
if (Thread.currentThread().isInterrupted()) {
System.out.println("优雅线程检测到中断信号,准备清理...");
break;
}
System.out.println("优雅线程执行任务 " + i);
// 模拟任务执行
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("优雅线程在任务执行中被中断");
// 重新设置中断标志,以便上层逻辑处理
Thread.currentThread().interrupt();
}
// 清理资源
System.out.println("优雅线程开始清理资源...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("优雅线程清理完成,退出");
}, "Graceful-Thread");
gracefulThread.start();
// 主线程等待2秒后中断
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断优雅线程");
gracefulThread.interrupt();
try {
gracefulThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 演示5:中断标志的维护
private static void demonstrateInterruptionFlag() {
System.out.println("\n--- 演示5:中断标志的维护 ---");
Thread flagTestThread = new Thread(() -> {
System.out.println("标志测试线程开始,中断状态: " +
Thread.currentThread().isInterrupted());
// 模拟一个会抛出InterruptedException的操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("捕获InterruptedException,中断状态: " +
Thread.currentThread().isInterrupted()); // false,被清除
}
System.out.println("异常处理后,中断状态: " +
Thread.currentThread().isInterrupted());
// 手动恢复中断状态
Thread.currentThread().interrupt();
System.out.println("手动恢复后,中断状态: " +
Thread.currentThread().isInterrupted());
// 使用 interrupted() 方法(会清除标志)
boolean wasInterrupted = Thread.interrupted();
System.out.println("interrupted()返回: " + wasInterrupted);
System.out.println("调用interrupted()后,中断状态: " +
Thread.currentThread().isInterrupted());
}, "Flag-Test-Thread");
flagTestThread.start();
// 主线程等待500ms后中断
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断标志测试线程");
flagTestThread.interrupt();
try {
flagTestThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
💻 守护线程详解
1. 守护线程的特性
守护线程(Daemon Thread)是一种特殊的线程,它的生命周期依赖于非守护线程:
核心特性:
- 后台运行:在后台提供服务和支持
- 生命周期依赖:当所有非守护线程结束时,JVM 会退出,不管守护线程是否执行完成
- 优先级低:通常用于执行后台任务
- 自动终止:JVM 退出时不保证 finally 块执行
/**
* 守护线程深度演示
*/
public class DaemonThreadDeepDive {
public static void main(String[] args) {
System.out.println("=== 守护线程深度演示 ===");
// 演示1:守护线程的基本特性
demonstrateBasicDaemon();
// 演示2:守护线程的自动终止
demonstrateDaemonAutoTermination();
// 演示3:守护线程的finally块不保证执行
demonstrateDaemonFinallyBlock();
// 演示4:守护线程的实用场景
demonstrateDaemonUseCases();
}
// 演示1:守护线程的基本特性
private static void demonstrateBasicDaemon() {
System.out.println("\n--- 演示1:守护线程的基本特性 ---");
Thread userThread = new Thread(() -> {
System.out.println("用户线程开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("用户线程执行完成");
}, "User-Thread");
Thread daemonThread = new Thread(() -> {
System.out.println("守护线程开始执行");
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(500);
System.out.println("守护线程执行中: " + (i + 1));
}
} catch (InterruptedException e) {
System.out.println("守护线程被中断");
Thread.currentThread().interrupt();
}
System.out.println("守护线程执行完成");
}, "Daemon-Thread");
// 设置为守护线程(必须在start之前)
daemonThread.setDaemon(true);
System.out.println("用户线程是否为守护线程: " + userThread.isDaemon());
System.out.println("守护线程是否为守护线程: " + daemonThread.isDaemon());
userThread.start();
daemonThread.start();
try {
userThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程和用户线程都完成了,程序即将退出");
}
// 演示2:守护线程的自动终止
private static void demonstrateDaemonAutoTermination() {
System.out.println("\n--- 演示2:守护线程的自动终止 ---");
Thread longRunningDaemon = new Thread(() -> {
int count = 0;
while (true) { // 无限循环
count++;
System.out.println("长期守护线程执行次数: " + count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("长期守护线程被中断");
Thread.currentThread().interrupt();
break;
}
}
}, "Long-Running-Daemon");
longRunningDaemon.setDaemon(true);
longRunningDaemon.start();
System.out.println("长期守护线程已启动");
// 主线程休眠3秒后退出
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程即将退出,长期守护线程将自动终止");
}
// 演示3:守护线程的finally块不保证执行
private static void demonstrateDaemonFinallyBlock() {
System.out.println("\n--- 演示3:守护线程的finally块不保证执行 ---");
Thread daemonWithFinally = new Thread(() -> {
try {
System.out.println("守护线程开始执行");
Thread.sleep(2000);
System.out.println("守护线程正常完成");
} catch (InterruptedException e) {
System.out.println("守护线程被中断");
Thread.currentThread().interrupt();
} finally {
System.out.println("守护线程的finally块执行");
// 这个块可能不会执行
}
}, "Daemon-With-Finally");
daemonWithFinally.setDaemon(true);
daemonWithFinally.start();
// 主线程只等待1秒就退出
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程退出,守护线程的finally块可能不会执行");
}
// 演示4:守护线程的实用场景
private static void demonstrateDaemonUseCases() {
System.out.println("\n--- 演示4:守护线程的实用场景 ---");
// 场景1:监控线程
Thread monitorThread = new Thread(() -> {
while (true) {
Runtime runtime = Runtime.getRuntime();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
System.out.printf("内存使用情况: 总内存=%dMB, 已用=%dMB, 空闲=%dMB%n",
totalMemory / 1024 / 1024,
usedMemory / 1024 / 1024,
freeMemory / 1024 / 1024);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("监控线程被中断");
Thread.currentThread().interrupt();
break;
}
}
}, "Memory-Monitor");
// 场景2:日志清理线程
Thread logCleanupThread = new Thread(() -> {
while (true) {
System.out.println("日志清理线程执行清理任务");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("日志清理线程被中断");
Thread.currentThread().interrupt();
break;
}
}
}, "Log-Cleanup");
monitorThread.setDaemon(true);
logCleanupThread.setDaemon(true);
monitorThread.start();
logCleanupThread.start();
System.out.println("守护线程已启动,执行后台任务");
// 主线程执行5秒后退出
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程退出,所有守护线程自动终止");
}
}
2. 守护线程 vs 非守护线程对比
| 特性 | 守护线程 | 非守护线程 |
|---|---|---|
| JVM退出条件 | 不阻止JVM退出 | 阻止JVM退出 |
| finally块执行 | 不保证执行 | 保证执行 |
| 用途 | 后台服务、监控、清理 | 主要业务逻辑 |
| 生命周期 | 依赖于非守护线程 | 独立 |
| 设置时机 | 必须在start()之前 | 无限制 |
🎯 实战练习
1. 基础练习 ⭐
任务: 编写程序观察所有线程状态转换
/**
* 基础练习:线程状态转换观察器
*/
public class BasicExercise {
public static void main(String[] args) {
System.out.println("=== 基础练习:线程状态转换观察器 ===");
// 创建状态观察器
ThreadStateObserver observer = new ThreadStateObserver();
// 演示各种状态转换
demonstrateAllStateTransitions(observer);
}
private static void demonstrateAllStateTransitions(ThreadStateObserver observer) {
System.out.println("\n--- 演示所有线程状态转换 ---");
// 1. NEW -> RUNNABLE -> TERMINATED
demonstrateBasicLifecycle(observer);
// 2. RUNNABLE -> TIMED_WAITING -> RUNNABLE
demonstrateTimedWaitingTransition(observer);
// 3. RUNNABLE -> BLOCKED -> RUNNABLE
demonstrateBlockedTransition(observer);
// 4. RUNNABLE -> WAITING -> RUNNABLE
demonstrateWaitingTransition(observer);
// 5. 复杂状态转换序列
demonstrateComplexTransitionSequence(observer);
}
// 1. 基本生命周期:NEW -> RUNNABLE -> TERMINATED
private static void demonstrateBasicLifecycle(ThreadStateObserver observer) {
System.out.println("\n1. 基本生命周期转换:");
Thread basicThread = new Thread(() -> {
System.out.println(" 基本线程执行中...");
}, "Basic-Thread");
observer.observeThread(basicThread, "创建后");
System.out.println(" 状态: " + basicThread.getState());
basicThread.start();
observer.observeThread(basicThread, "启动后");
System.out.println(" 状态: " + basicThread.getState());
try {
basicThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(basicThread, "完成后");
System.out.println(" 状态: " + basicThread.getState());
}
// 2. TIMED_WAITING 状态转换
private static void demonstrateTimedWaitingTransition(ThreadStateObserver observer) {
System.out.println("\n2. TIMED_WAITING 状态转换:");
Thread sleepingThread = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Sleeping-Thread");
sleepingThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(sleepingThread, "休眠中");
System.out.println(" 状态: " + sleepingThread.getState());
try {
sleepingThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(sleepingThread, "休眠完成");
System.out.println(" 状态: " + sleepingThread.getState());
}
// 3. BLOCKED 状态转换
private static void demonstrateBlockedTransition(ThreadStateObserver observer) {
System.out.println("\n3. BLOCKED 状态转换:");
Object lock = new Object();
Thread lockHolder = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Lock-Holder");
Thread blockedThread = new Thread(() -> {
synchronized (lock) {
System.out.println(" 被阻塞线程获取锁成功");
}
}, "Blocked-Thread");
lockHolder.start();
blockedThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(blockedThread, "等待锁时");
System.out.println(" 状态: " + blockedThread.getState());
try {
lockHolder.join();
blockedThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(blockedThread, "获取锁后");
System.out.println(" 状态: " + blockedThread.getState());
}
// 4. WAITING 状态转换
private static void demonstrateWaitingTransition(ThreadStateObserver observer) {
System.out.println("\n4. WAITING 状态转换:");
Thread waitingThread = new Thread(() -> {
synchronized (BasicExercise.class) {
try {
BasicExercise.class.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Waiting-Thread");
Thread notifierThread = new Thread(() -> {
try {
Thread.sleep(1000);
synchronized (BasicExercise.class) {
BasicExercise.class.notifyAll();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Notifier-Thread");
waitingThread.start();
notifierThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(waitingThread, "等待时");
System.out.println(" 状态: " + waitingThread.getState());
try {
waitingThread.join();
notifierThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(waitingThread, "被唤醒后");
System.out.println(" 状态: " + waitingThread.getState());
}
// 5. 复杂状态转换序列
private static void demonstrateComplexTransitionSequence(ThreadStateObserver observer) {
System.out.println("\n5. 复杂状态转换序列:");
Thread complexThread = new Thread(() -> {
try {
// RUNNABLE -> TIMED_WAITING
Thread.sleep(500);
// RUNNABLE -> BLOCKED
synchronized (observer) {
// RUNNABLE -> WAITING
observer.wait(1000);
}
// 继续执行
System.out.println(" 复杂线程完成所有状态转换");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Complex-Thread");
observer.observeThread(complexThread, "初始状态");
System.out.println(" 初始状态: " + complexThread.getState());
complexThread.start();
observer.observeThread(complexThread, "启动后");
System.out.println(" 启动后状态: " + complexThread.getState());
// 监控状态变化
for (int i = 0; i < 8; i++) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(complexThread, "监控点" + (i + 1));
System.out.println(" 监控点" + (i + 1) + "状态: " + complexThread.getState());
}
try {
complexThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
observer.observeThread(complexThread, "最终状态");
System.out.println(" 最终状态: " + complexThread.getState());
}
// 线程状态观察器
private static class ThreadStateObserver {
public void observeThread(Thread thread, String phase) {
System.out.printf(" [%s] %s: %s%n",
thread.getName(), phase, thread.getState());
}
}
}
2. 进阶练习 ⭐⭐
任务: 实现一个可中断的任务执行器
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 进阶练习:可中断的任务执行器
*/
public class AdvancedExercise {
public static void main(String[] args) {
System.out.println("=== 进阶练习:可中断的任务执行器 ===");
// 创建任务执行器
InterruptibleTaskExecutor executor = new InterruptibleTaskExecutor(3);
// 测试基本功能
testBasicExecution(executor);
// 测试中断功能
testInterruption(executor);
// 测试任务队列管理
testTaskQueueManagement(executor);
// 关闭执行器
executor.shutdown();
}
// 测试基本执行功能
private static void testBasicExecution(InterruptibleTaskExecutor executor) {
System.out.println("\n--- 测试1:基本执行功能 ---");
CountDownLatch latch1 = new CountDownLatch(3);
// 提交3个任务
for (int i = 1; i <= 3; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("任务 " + taskId + " 开始执行");
try {
Thread.sleep(1000); // 模拟工作
} catch (InterruptedException e) {
System.out.println("任务 " + taskId + " 被中断");
Thread.currentThread().interrupt();
}
System.out.println("任务 " + taskId + " 完成");
latch1.countDown();
});
}
try {
latch1.await();
System.out.println("所有任务完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 测试中断功能
private static void testInterruption(InterruptibleTaskExecutor executor) {
System.out.println("\n--- 测试2:中断功能 ---");
AtomicBoolean longTaskStarted = new AtomicBoolean(false);
// 提交一个长时间任务
Future<?> longTask = executor.submit(() -> {
longTaskStarted.set(true);
System.out.println("长时间任务开始执行");
try {
for (int i = 0; i < 10; i++) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("长时间任务检测到中断信号");
break;
}
Thread.sleep(500);
System.out.println("长时间任务进度: " + (i + 1) + "/10");
}
} catch (InterruptedException e) {
System.out.println("长时间任务捕获中断异常");
Thread.currentThread().interrupt();
}
System.out.println("长时间任务结束");
});
// 等待任务开始
while (!longTaskStarted.get()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 主线程等待2秒后中断任务
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("主线程中断长时间任务");
longTask.cancel(true);
try {
longTask.get(1, TimeUnit.SECONDS);
} catch (CancellationException e) {
System.out.println("任务被成功取消");
} catch (Exception e) {
System.out.println("任务异常: " + e.getMessage());
}
}
// 测试任务队列管理
private static void testTaskQueueManagement(InterruptibleTaskExecutor executor) {
System.out.println("\n--- 测试3:任务队列管理 ---");
CountDownLatch latch2 = new CountDownLatch(5);
AtomicInteger completedTasks = new AtomicInteger(0);
// 提交5个任务,观察队列管理
for (int i = 1; i <= 5; i++) {
final int taskId = i;
Future<?> future = executor.submit(() -> {
System.out.println("队列测试任务 " + taskId + " 开始执行");
try {
Thread.sleep(800);
} catch (InterruptedException e) {
System.out.println("队列测试任务 " + taskId + " 被中断");
Thread.currentThread().interrupt();
}
System.out.println("队列测试任务 " + taskId + " 完成");
completedTasks.incrementAndGet();
latch2.countDown();
});
// 每隔200ms提交一个任务
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
try {
latch2.await();
System.out.println("队列测试完成,完成任务数: " + completedTasks.get());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* 可中断的任务执行器
*/
class InterruptibleTaskExecutor {
private final ExecutorService executor;
private final BlockingQueue<Future<?>> runningTasks;
public InterruptibleTaskExecutor(int poolSize) {
this.executor = Executors.newFixedThreadPool(poolSize);
this.runningTasks = new LinkedBlockingQueue<>();
}
public Future<?> submit(Runnable task) {
Future<?> future = executor.submit(() -> {
try {
runningTasks.add(future);
task.run();
} finally {
runningTasks.remove(future);
}
});
return future;
}
public void interruptAll() {
System.out.println("中断所有运行中的任务...");
for (Future<?> task : runningTasks) {
task.cancel(true);
}
}
public void shutdown() {
System.out.println("关闭任务执行器...");
executor.shutdown();
try {
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("强制关闭执行器");
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
System.out.println("任务执行器已关闭");
}
}
3. 挑战练习 ⭐⭐⭐
任务: 创建一个线程状态监控工具
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
/**
* 挑战练习:线程状态监控工具
*/
public class ChallengeExercise {
public static void main(String[] args) {
System.out.println("=== 挑战练习:线程状态监控工具 ===");
// 创建监控工具
ThreadMonitor monitor = new ThreadMonitor();
// 启动监控
monitor.startMonitoring();
// 创建各种类型的线程进行监控
createMonitoredThreads(monitor);
// 运行监控一段时间
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 停止监控并显示报告
monitor.stopMonitoring();
monitor.displayReport();
}
private static void createMonitoredThreads(ThreadMonitor monitor) {
System.out.println("\n--- 创建被监控的线程 ---");
// 1. CPU密集型线程
Thread cpuThread = new Thread(() -> {
long count = 0;
while (!Thread.currentThread().isInterrupted()) {
count++;
if (count % 100_000_000 == 0) {
System.out.println("CPU线程计数: " + count);
}
}
}, "CPU-Intensive-Thread");
// 2. IO模拟线程
Thread ioThread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("IO线程完成一次操作");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}, "IO-Simulation-Thread");
// 3. 锁竞争线程
Object lock = new Object();
Thread lockThread1 = new Thread(() -> {
synchronized (lock) {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(2000);
System.out.println("锁线程1持有锁");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
}, "Lock-Thread-1");
Thread lockThread2 = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
synchronized (lock) {
System.out.println("锁线程2获取锁");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}, "Lock-Thread-2");
// 4. 等待线程
Thread waitingThread = new Thread(() -> {
synchronized (ChallengeExercise.class) {
try {
ChallengeExercise.class.wait();
System.out.println("等待线程被唤醒");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Waiting-Thread");
// 启动所有线程并注册监控
Thread[] threads = {cpuThread, ioThread, lockThread1, lockThread2, waitingThread};
for (Thread thread : threads) {
monitor.registerThread(thread);
thread.start();
}
// 5秒后通知等待线程
new Timer().schedule(new TimerTask() {
@Override
public void run() {
synchronized (ChallengeExercise.class) {
ChallengeExercise.class.notifyAll();
}
}
}, 5000);
// 8秒后中断所有线程
new Timer().schedule(new TimerTask() {
@Override
public void run() {
for (Thread thread : threads) {
thread.interrupt();
}
}
}, 8000);
}
}
/**
* 线程状态监控工具
*/
class ThreadMonitor {
private final Map<String, ThreadInfo> monitoredThreads = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private final AtomicLong monitoringCount = new AtomicLong(0);
private volatile boolean isMonitoring = false;
// 注册要监控的线程
public void registerThread(Thread thread) {
ThreadInfo info = new ThreadInfo(thread);
monitoredThreads.put(thread.getName(), info);
System.out.println("注册监控线程: " + thread.getName());
}
// 开始监控
public void startMonitoring() {
if (isMonitoring) {
return;
}
isMonitoring = true;
System.out.println("开始线程状态监控...");
scheduler.scheduleAtFixedRate(() -> {
if (isMonitoring) {
performMonitoring();
}
}, 0, 500, TimeUnit.MILLISECONDS); // 每500ms监控一次
}
// 停止监控
public void stopMonitoring() {
isMonitoring = false;
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(2, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
Thread.currentThread().interrupt();
}
System.out.println("停止线程状态监控");
}
// 执行监控
private void performMonitoring() {
long count = monitoringCount.incrementAndGet();
if (count % 10 == 1) { // 每5秒打印一次状态摘要
System.out.println("\n=== 监控报告 #" + (count / 10 + 1) + " ===");
printStateSummary();
}
// 更新每个线程的状态信息
for (ThreadInfo info : monitoredThreads.values()) {
info.updateState();
}
}
// 打印状态摘要
private void printStateSummary() {
Map<Thread.State, Integer> stateCount = new HashMap<>();
for (ThreadInfo info : monitoredThreads.values()) {
Thread.State state = info.getCurrentState();
stateCount.merge(state, 1, Integer::sum);
}
System.out.println("当前线程状态分布:");
for (Map.Entry<Thread.State, Integer> entry : stateCount.entrySet()) {
System.out.printf(" %s: %d 个线程%n", entry.getKey(), entry.getValue());
}
}
// 显示详细报告
public void displayReport() {
System.out.println("\n=== 线程状态监控详细报告 ===");
System.out.println("监控总次数: " + monitoringCount.get());
System.out.println("监控线程数: " + monitoredThreads.size());
for (ThreadInfo info : monitoredThreads.values()) {
System.out.println("\n--- " + info.getThreadName() + " ---");
System.out.println("最终状态: " + info.getCurrentState());
System.out.println("是否存活: " + info.getThread().isAlive());
System.out.println("是否被中断: " + info.getThread().isInterrupted());
System.out.println("优先级: " + info.getThread().getPriority());
System.out.println("是否为守护线程: " + info.getThread().isDaemon());
// 显示状态历史
System.out.println("状态历史:");
info.getStateHistory().forEach((state, duration) -> {
System.out.printf(" %s: %.2f 秒%n", state, duration / 1000.0);
});
}
// 显示状态统计
System.out.println("\n=== 总体状态统计 ===");
displayOverallStatistics();
}
// 显示总体统计
private void displayOverallStatistics() {
Map<Thread.State, Long> totalStateTime = new HashMap<>();
for (ThreadInfo info : monitoredThreads.values()) {
for (Map.Entry<Thread.State, Long> entry : info.getStateHistory().entrySet()) {
totalStateTime.merge(entry.getKey(), entry.getValue(), Long::sum);
}
}
System.out.println("各状态总时间:");
for (Map.Entry<Thread.State, Long> entry : totalStateTime.entrySet()) {
System.out.printf(" %s: %.2f 秒%n", entry.getKey(), entry.getValue() / 1000.0);
}
}
// 线程信息类
private static class ThreadInfo {
private final Thread thread;
private Thread.State currentState;
private Thread.State lastState;
private long lastStateChangeTime;
private final Map<Thread.State, Long> stateHistory = new HashMap<>();
public ThreadInfo(Thread thread) {
this.thread = thread;
this.currentState = thread.getState();
this.lastState = currentState;
this.lastStateChangeTime = System.currentTimeMillis();
}
public void updateState() {
Thread.State newState = thread.getState();
if (newState != currentState) {
// 记录当前状态的持续时间
long duration = System.currentTimeMillis() - lastStateChangeTime;
stateHistory.merge(lastState, duration, Long::sum);
// 更新状态
lastState = currentState;
currentState = newState;
lastStateChangeTime = System.currentTimeMillis();
}
}
public Thread getThread() { return thread; }
public String getThreadName() { return thread.getName(); }
public Thread.State getCurrentState() { return currentState; }
public Map<Thread.State, Long> getStateHistory() { return new HashMap<>(stateHistory); }
}
}
📝 今日总结
核心要点回顾
-
线程六大状态:
- NEW: 线程创建但未启动
- RUNNABLE: 可运行状态(包含就绪和运行)
- BLOCKED: 等待获取锁
- WAITING: 无限期等待(wait、join)
- TIMED_WAITING: 计时等待(sleep、wait(timeout))
- TERMINATED: 线程执行完成或异常退出
-
线程控制方法:
- sleep() : 让线程休眠,不释放锁,可中断
- join() : 等待其他线程完成,释放锁,支持超时
- yield() : 礼让CPU时间片,只是建议,不保证生效
- interrupt() : 协作式中断机制,设置中断标志
-
中断机制:
- 中断是一种协作机制,不是强制终止
- 不同状态下线程对中断的响应不同
- 正确处理中断标志和InterruptedException
-
守护线程:
- 在后台提供服务的线程
- 不阻止JVM退出
- finally块不保证执行
最佳实践建议
-
线程中断处理:
- 优先使用
isInterrupted()检查中断状态 - 捕获
InterruptedException后重新设置中断标志 - 设计可中断的任务逻辑
- 优先使用
-
状态管理:
- 避免长时间处于阻塞或等待状态
- 合理使用超时机制
- 监控线程状态变化
-
资源清理:
- 守护线程的finally块可能不执行
- 使用注册关闭钩子进行资源清理
- 优雅关闭线程池
-
性能优化:
- 避免不必要的线程状态切换
- 合理设置线程优先级
- 使用线程池管理线程生命周期
下节预告
明天我们将深入学习 synchronized 底层实现,包括:
- synchronized 的三种应用方式
- 对象头和 Mark Word 结构
- 锁升级过程:偏向锁 → 轻量级锁 → 重量级锁
- JVM 锁优化机制
课后作业
-
理论作业:
- 详细描述线程状态转换的条件和过程
- 分析不同线程控制方法的适用场景
- 解释中断机制的协作原理
-
实践作业:
- 实现一个线程状态可视化工具
- 创建一个支持优雅关闭的服务框架
- 分析生产环境中线程状态异常的原因
学习提示: 线程生命周期是并发编程的基础,理解状态转换机制对于编写稳定的多线程程序至关重要。建议结合实际场景多实践,加深对各种状态和控制方法的理解。