1. 线程生命周期深度解析
在Java多线程编程中,理解线程的生命周期是掌握线程池的基础。线程从创建到销毁会经历多个状态变化,这些状态定义在java.lang.Thread.State枚举类中。让我们深入分析每个状态的含义和转换条件。
1.1 线程状态详解
NEW(新建状态):当线程对象通过new Thread()创建后,但尚未调用start()方法时的状态。此时线程还未被操作系统分配系统资源。
java复制Thread thread = new Thread(); // 线程处于NEW状态
System.out.println(thread.getState()); // 输出NEW
RUNNABLE(可运行状态):调用start()方法后,线程进入就绪状态。此时线程已经具备运行条件,等待CPU调度。需要注意的是,很多开发者容易混淆RUNNABLE和RUNNING状态。实际上在Java线程模型中,RUNNABLE包含了传统意义上的就绪和运行两种状态。
BLOCKED(阻塞状态):当线程试图获取一个对象的同步锁时,如果该锁已被其他线程持有,当前线程就会进入BLOCKED状态。只有当锁被释放时,系统才会从阻塞队列中唤醒线程。
WAITING(无限等待):当线程调用Object.wait()、Thread.join()或LockSupport.park()方法时会进入此状态。与TIMED_WAITING不同,WAITING状态需要其他线程显式唤醒。
TIMED_WAITING(限时等待):通过Thread.sleep(long)、Object.wait(long)等方法进入的状态。与WAITING的主要区别是它会在指定时间后自动唤醒。
TERMINATED(终止状态):线程执行完run()方法或抛出未捕获异常后的最终状态。处于此状态的线程不能再被启动。
1.2 状态转换实战图解
线程状态转换遵循严格的规则,理解这些规则对调试多线程程序至关重要:
- NEW → RUNNABLE:调用start()方法
- RUNNABLE → BLOCKED:尝试获取锁失败
- RUNNABLE → WAITING:调用wait()/join()
- RUNNABLE → TIMED_WAITING:调用sleep()/wait(timeout)
- 各种等待状态 → RUNNABLE:条件满足/超时/被中断
- RUNNABLE → TERMINATED:执行完成
重要提示:直接从NEW状态调用run()方法不会启动新线程,而是在当前线程中同步执行。这是新手常犯的错误。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线程池核心原理
线程池是Java并发编程中的重要工具,它通过复用线程减少创建和销毁的开销。Java通过Executor框架提供线程池支持。
2.1 为什么需要线程池
直接创建线程存在几个严重问题:
- 线程创建和销毁开销大
- 无限制创建线程会导致系统资源耗尽
- 缺乏统一管理,难以监控和调优
线程池通过以下机制解决这些问题:
- 线程复用:工作线程执行完任务后不销毁,继续执行新任务
- 资源控制:通过参数限制最大线程数
- 任务队列:缓冲来不及处理的任务
2.2 JDK内置线程池
Java提供了几种预配置的线程池工厂方法:
- newCachedThreadPool:弹性线程
