1540 字
约 5 分钟
3
Java多线程教程第3章:线程生命周期

Java多线程教程第3章:线程生命周期

章节头部 第3章

🔄 线程生命周期

深入理解线程的生命周期和状态转换,掌握线程状态的查看和监控方法 学习目标

学习目标

  • 深入理解线程的生命周期和状态转换
  • 掌握线程状态的查看和监控方法
  • 学会控制线程的状态转换
  • 理解线程调度的基本原理
  • 掌握线程的优雅停止方法

线程状态详解

线程状态详解

在Java中,线程的生命周期由Thread.State枚举定义,包含6个状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。理解这些状态及其转换条件是掌握多线程编程的基础。

线程状态转换图

NEW→RUNNABLE→TERMINATEDBLOCKED↕RUNNABLE↕WAITINGTIMED_WAITING↕RUNNABLE

六种线程状态

NEW(新建)线程对象已创建但尚未调用start()方法。此时线程还没有开始执行。RUNNABLE(可运行)线程正在Java虚拟机中执行,但可能正在等待操作系统的其他资源,如CPU时间片。BLOCKED(阻塞)线程被阻塞等待监视器锁,通常发生在synchronized代码块或方法中。WAITING(等待)线程无限期等待另一个线程执行特定操作,如调用Object.wait()或Thread.join()。TIMED_WAITING(超时等待)线程等待指定时间,如Thread.sleep()、Object.wait(timeout)等。TERMINATED(终止)线程执行完毕或因异常而终止,run()方法执行完成。

重要提示

RUNNABLE状态在Java中包含了操作系统层面的READY和RUNNING状态,这是因为Java无法精确区分线程是在等待CPU时间片还是正在执行。 状态转换条件

状态转换条件

线程状态之间的转换有明确的触发条件,理解这些条件有助于我们更好地控制线程的行为。

主要状态转换

  • NEW → RUNNABLE:调用Thread.start()方法
  • RUNNABLE → BLOCKED:尝试获取synchronized锁失败
  • BLOCKED → RUNNABLE:成功获取synchronized锁
  • RUNNABLE → WAITING:调用Object.wait()、Thread.join()等方法
  • WAITING → RUNNABLE:其他线程调用Object.notify()、notifyAll()或join的线程执行完毕
  • RUNNABLE → TIMED_WAITING:调用Thread.sleep()、Object.wait(timeout)等方法
  • TIMED_WAITING → RUNNABLE:超时时间到达或被其他线程唤醒
  • RUNNABLE → TERMINATED:run()方法执行完毕或抛出未捕获异常
// 演示线程状态转换
public class ThreadStateDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                System.out.println("线程开始执行");
                Thread.sleep(2000); // TIMED_WAITING
                System.out.println("线程执行完毕");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        System.out.println("创建后状态: " + thread.getState()); // NEW
        
        thread.start();
        System.out.println("启动后状态: " + thread.getState()); // RUNNABLE
        
        Thread.sleep(100);
        System.out.println("睡眠中状态: " + thread.getState()); // TIMED_WAITING
        
        thread.join();
        System.out.println("结束后状态: " + thread.getState()); // TERMINATED
    }
}

线程调度机制

线程调度机制

Java虚拟机采用抢占式调度模型,线程的执行顺序由操作系统的线程调度器决定。理解调度机制有助于我们编写更高效的多线程程序。

调度策略

抢占式调度高优先级线程可以抢占低优先级线程的CPU时间,但优先级只是调度的参考,不保证执行顺序。时间片轮转同优先级线程采用时间片轮转方式,每个线程获得相等的CPU时间片。公平调度现代JVM尽量保证线程调度的公平性,避免线程饥饿现象。

注意事项

不要依赖线程优先级来控制程序逻辑,因为不同操作系统的调度策略可能不同。应该使用同步机制来确保程序的正确性。 线程监控工具

线程监控工具

Java提供了多种工具来监控和分析线程状态,这些工具对于调试和性能优化非常重要。

常用监控工具

jstack 命令行工具,用于生成线程堆栈快照,分析线程状态和死锁问题。

jstack <pid>

jconsole图形化监控工具,可以实时查看线程状态、内存使用情况等。VisualVM功能强大的可视化工具,提供线程分析、性能分析等功能。

// 程序内监控线程状态
public class ThreadMonitor {
    public static void monitorThread(Thread thread) {
        System.out.println("线程名称: " + thread.getName());
        System.out.println("线程状态: " + thread.getState());
        System.out.println("是否存活: " + thread.isAlive());
        System.out.println("是否守护线程: " + thread.isDaemon());
        System.out.println("线程优先级: " + thread.getPriority());
    }
    
    public static void printAllThreads() {
        ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
        while (rootGroup.getParent() != null) {
            rootGroup = rootGroup.getParent();
        }
        
        Thread[] threads = new Thread[rootGroup.activeCount()];
        rootGroup.enumerate(threads);
        
        for (Thread thread : threads) {
            if (thread != null) {
                System.out.println(thread.getName() + ": " + thread.getState());
            }
        }
    }
}

优雅停止线程

优雅停止线程

正确停止线程是多线程编程中的重要技能。Java提供了interrupt机制来实现线程的优雅停止,避免使用已废弃的stop()方法。

停止线程的方法

interrupt机制通过调用interrupt()方法设置中断标志,线程检查标志后自行停止。标志位控制使用volatile布尔变量作为停止标志,线程定期检查标志状态。资源清理在线程停止前确保释放所有资源,如关闭文件、网络连接等。

// 使用interrupt机制优雅停止线程
public class GracefulShutdownDemo {
    private static class InterruptibleTask implements Runnable {
        @Override
        public void run() {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    // 执行任务
                    System.out.println("执行任务中...");
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                // 恢复中断状态
                Thread.currentThread().interrupt();
                System.out.println("线程被中断,开始清理资源");
            } finally {
                // 清理资源
                cleanup();
            }
        }
        
        private void cleanup() {
            System.out.println("资源清理完成");
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(new InterruptibleTask());
        worker.start();
        
        // 运行3秒后停止
        Thread.sleep(3000);
        worker.interrupt();
        
        // 等待线程结束
        worker.join();
        System.out.println("主线程结束");
    }
}

最佳实践

永远不要使用Thread.stop()方法,它已被废弃且不安全在可能阻塞的操作前检查中断状态捕获InterruptedException后要恢复中断状态使用finally块确保资源得到正确清理为长时间运行的任务提供取消机制 章节导航 上一章:线程基础操作 返回目录 下一章:线程安全问题

Java多线程教程第3章:线程生命周期
http://www.clxhxhhr.top/posts/3133/
作者
clxstart
发布于
2026-09-24
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。