Day 3: 线程生命周期与状态转换

36 阅读22分钟

今日金句: "理解线程的生命周期,就是掌握并发编程的节奏。"

📚 课程概述

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 状态转换图

image.png

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 状态:设置中断标志,线程自行检查
  • 如果线程处于 BLOCKEDWAITING 状态:抛出 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); }
    }
}

📝 今日总结

核心要点回顾

  1. 线程六大状态

    • NEW: 线程创建但未启动
    • RUNNABLE: 可运行状态(包含就绪和运行)
    • BLOCKED: 等待获取锁
    • WAITING: 无限期等待(wait、join)
    • TIMED_WAITING: 计时等待(sleep、wait(timeout))
    • TERMINATED: 线程执行完成或异常退出
  2. 线程控制方法

    • sleep() : 让线程休眠,不释放锁,可中断
    • join() : 等待其他线程完成,释放锁,支持超时
    • yield() : 礼让CPU时间片,只是建议,不保证生效
    • interrupt() : 协作式中断机制,设置中断标志
  3. 中断机制

    • 中断是一种协作机制,不是强制终止
    • 不同状态下线程对中断的响应不同
    • 正确处理中断标志和InterruptedException
  4. 守护线程

    • 在后台提供服务的线程
    • 不阻止JVM退出
    • finally块不保证执行

最佳实践建议

  1. 线程中断处理

    • 优先使用 isInterrupted() 检查中断状态
    • 捕获 InterruptedException 后重新设置中断标志
    • 设计可中断的任务逻辑
  2. 状态管理

    • 避免长时间处于阻塞或等待状态
    • 合理使用超时机制
    • 监控线程状态变化
  3. 资源清理

    • 守护线程的finally块可能不执行
    • 使用注册关闭钩子进行资源清理
    • 优雅关闭线程池
  4. 性能优化

    • 避免不必要的线程状态切换
    • 合理设置线程优先级
    • 使用线程池管理线程生命周期

下节预告

明天我们将深入学习 synchronized 底层实现,包括:

  • synchronized 的三种应用方式
  • 对象头和 Mark Word 结构
  • 锁升级过程:偏向锁 → 轻量级锁 → 重量级锁
  • JVM 锁优化机制

课后作业

  1. 理论作业

    • 详细描述线程状态转换的条件和过程
    • 分析不同线程控制方法的适用场景
    • 解释中断机制的协作原理
  2. 实践作业

    • 实现一个线程状态可视化工具
    • 创建一个支持优雅关闭的服务框架
    • 分析生产环境中线程状态异常的原因

学习提示: 线程生命周期是并发编程的基础,理解状态转换机制对于编写稳定的多线程程序至关重要。建议结合实际场景多实践,加深对各种状态和控制方法的理解。