线程池
1. 线程池概述与设计理念
1.1 为什么需要线程池?
在多线程编程中,频繁创建和销毁线程会带来巨大的性能开销:
graph TD
A[传统线程创建] --> B[系统调用开销]
A --> C[内存分配开销]
A --> D[线程切换开销]
E[线程池设计] --> F[线程复用]
E --> G[资源控制]
E --> H[任务队列管理]
B --> I[性能问题]
C --> I
D --> I
F --> J[高性能]
G --> J
H --> J
1.2 线程池核心优势
- 线程复用:避免频繁创建销毁线程的开销
- 资源控制:限制并发线程数量,防止资源耗尽
- 任务管理:提供任务队列,支持异步执行
- 统一管理:集中管理线程生命周期
2. 线程池整体执行流程图
7.1 ThreadPoolExecutor完整执行流程
flowchart TD
A[任务提交 execute/submit] --> B{线程池状态检查}
B -->|SHUTDOWN/STOP| Z[抛出RejectedExecutionException]
B -->|RUNNING| C{当前线程数 < 核心线程数?}
C -->|是| D[创建核心线程]
D --> E[addWorker成功?]
E -->|是| F[启动新线程执行任务]
E -->|否| G[创建失败]
C -->|否| H{工作队列是否已满?}
H -->|否| I[任务入队]
I --> J{入队成功?}
J -->|是| K[等待工作线程获取]
J -->|否| L{当前线程数 < 最大线程数?}
H -->|是| L
L -->|是| M[创建非核心线程]
M --> N[addWorker成功?]
N -->|是| O[启动新线程执行任务]
N -->|否| P[执行拒绝策略]
L -->|否| P
F --> Q[Worker.run]
O --> Q
K --> R[Worker获取任务]
R --> Q
Q --> S[runWorker循环]
S --> T{getTask获取任务}
T -->|获取到| U[执行任务]
T -->|获取不到| V[线程退出]
U --> W[beforeExecute]
W --> X[task.run]
X --> Y[afterExecute]
Y --> S
V --> AA[processWorkerExit]
AA --> BB[从workers移除]
style A fill:#e1f5fe
style F fill:#c8e6c9
style O fill:#c8e6c9
style X fill:#fff3e0
style P fill:#ffcdd2
style Z fill:#ffcdd2
2.2 Worker线程生命周期
stateDiagram-v2
[*] --> NEW: Worker创建
NEW --> RUNNABLE: thread.start()
RUNNABLE --> WAITING: getTask()等待任务
WAITING --> RUNNABLE: 获取到任务
RUNNABLE --> TIMED_WAITING: poll()超时等待
TIMED_WAITING --> RUNNABLE: 获取到任务
TIMED_WAITING --> TERMINATED: 超时退出
WAITING --> TERMINATED: 线程池关闭
RUNNABLE --> TERMINATED: 任务执行完成且无新任务
note right of NEW
Worker构造时:
setState(-1)
创建Thread
设置firstTask
end note
note right of RUNNABLE
执行任务时:
获取独占锁
执行beforeExecute
运行task.run()
执行afterExecute
释放锁
end note
2.3 线程池状态转换图
stateDiagram-v2
[*] --> RUNNING: 线程池创建
RUNNING --> SHUTDOWN: shutdown()
RUNNING --> STOP: shutdownNow()
SHUTDOWN --> STOP: shutdownNow()
SHUTDOWN --> TIDYING: 队列为空且工作线程为0
STOP --> TIDYING: 工作线程为0
TIDYING --> TERMINATED: terminated()钩子完成
note right of RUNNING
状态值: -1
接受新任务
处理队列中任务
end note
note right of SHUTDOWN
状态值: 0
不接受新任务
继续处理队列任务
中断空闲线程
end note
note right of STOP
状态值: 1
不接受新任务
不处理队列任务
中断所有线程
end note
note right of TIDYING
状态值: 2
所有任务已终止
workerCount为0
即将调用terminated()
end note
note right of TERMINATED
状态值: 3
terminated()执行完成
线程池完全关闭
end note
2.4 任务执行时序图
sequenceDiagram
participant C as 客户端
participant T as ThreadPoolExecutor
participant W as Worker线程
participant Q as 工作队列
participant Task as 任务
C->>T: execute(task)
T->>T: 检查线程池状态
alt 核心线程数未满
T->>W: 创建新Worker
W->>W: 启动线程
W->>Task: 执行firstTask
else 核心线程数已满
T->>Q: offer(task)
alt 入队成功
Q-->>T: 入队成功
W->>Q: getTask()
Q-->>W: 返回任务
W->>Task: 执行任务
else 入队失败且未达最大线程数
T->>W: 创建非核心Worker
W->>W: 启动线程
W->>Task: 执行任务
else 达到最大线程数
T->>T: 执行拒绝策略
T-->>C: 抛出异常或其他处理
end
end
W->>W: beforeExecute()
W->>Task: task.run()
W->>W: afterExecute()
W->>W: 更新完成任务计数
loop 继续获取任务
W->>Q: getTask()
alt 获取到任务
Q-->>W: 返回任务
W->>Task: 执行新任务
else 超时或线程池关闭
Q-->>W: 返回null
W->>T: processWorkerExit()
T->>T: 从workers移除Worker
end
end
3. Executors工厂类源码解析
3.1 Executors类设计模式
Executors类采用工厂模式,为不同场景提供预配置的线程池实例:
graph LR
A[Executors工厂类] --> B[newFixedThreadPool]
A --> C[newCachedThreadPool]
A --> D[newSingleThreadExecutor]
A --> E[newScheduledThreadPool]
B --> F[ThreadPoolExecutor]
C --> F
D --> G[FinalizableDelegatedExecutorService]
E --> H[ScheduledThreadPoolExecutor]
G --> F
H --> F
3.2 工厂方法通用模式
// Executors工厂方法的通用模式
public static ExecutorService newXxxThreadPool(参数...) {
return new ThreadPoolExecutor(
corePoolSize, // 核心线程数
maximumPoolSize, // 最大线程数
keepAliveTime, // 线程存活时间
unit, // 时间单位
workQueue, // 工作队列
threadFactory, // 线程工厂(可选)
handler // 拒绝策略(可选)
);
}
4. 四种默认线程池详细分析
4.1 FixedThreadPool - 固定大小线程池
4.1.1 源码分析
/**
* 创建固定大小的线程池
* @param nThreads 线程池大小
* @return 线程池实例
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(
nThreads, // corePoolSize = nThreads
nThreads, // maximumPoolSize = nThreads
0L, // keepAliveTime = 0(核心线程不会超时)
TimeUnit.MILLISECONDS, // 时间单位
new LinkedBlockingQueue<Runnable>() // 无界队列
);
}
// 支持自定义ThreadFactory的版本
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(
nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory // 自定义线程工厂
);
}
4.1.2 执行流程
flowchart TD
A["客户端提交任务"] --> B{"当前线程数 < corePoolSize?"}
B -->|是| C["创建新的核心线程执行任务"]
B -->|否| D{"任务队列是否已满?"}
D -->|否| E["任务加入LinkedBlockingQueue"]
D -->|是| F{"当前线程数 < maximumPoolSize?"}
F -->|是| G["创建新的非核心线程"]
F -->|否| H["执行拒绝策略"]
C --> I["线程执行任务"]
E --> J["空闲线程从队列获取任务"]
G --> I
J --> I
I --> K["任务执行完成"]
K --> L{"线程是否超时?"}
L -->|否| M["继续从队列获取任务"]
L -->|是| N["线程销毁"]
M --> J
style A fill:#e1f5fe
style C fill:#c8e6c9
style E fill:#fff3e0
style G fill:#f3e5f5
style H fill:#ffcdd2
4.1.3 适用场景与注意事项
适用场景:
- CPU密集型任务
- 需要控制并发线程数量的场景
- 任务执行时间相对均匀
注意事项:
// 潜在的OOM风险
ExecutorService executor = Executors.newFixedThreadPool(10);
// 如果任务提交速度 > 任务执行速度,队列会无限增长
for (int i = 0; i < Integer.MAX_VALUE; i++) {
executor.submit(() -> {
try {
Thread.sleep(1000); // 模拟耗时任务
}
}
4.2 CachedThreadPool - 缓存线程池
4.2.1 源码分析
/**
* 创建可缓存的线程池
* @return 线程池实例
*/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(
0, // corePoolSize = 0(无核心线程)
Integer.MAX_VALUE, // maximumPoolSize = Integer.MAX_VALUE
60L, // keepAliveTime = 60秒
TimeUnit.SECONDS, // 时间单位
new SynchronousQueue<Runnable>() // 同步队列(无容量)
);
}
// 支持自定义ThreadFactory的版本
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(
0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory
);
}
4.2.2 SynchronousQueue机制
graph TD
A[SynchronousQueue特性] --> B[无存储容量]
A --> C[直接传递]
A --> D[阻塞操作]
B --> E[不存储任务]
C --> F[生产者直接传递给消费者]
D --> G[put/take操作会阻塞]
E --> H[每个插入操作必须等待移除操作]
F --> H
G --> H
H --> I[适合传递性设计]
4.2.3 执行流程分析
sequenceDiagram
participant Client
participant CachedThreadPool
participant SynchronousQueue
participant WorkerThread
Client->>CachedThreadPool: submit(task)
alt 有空闲线程
CachedThreadPool->>SynchronousQueue: offer(task)
SynchronousQueue->>WorkerThread: 直接传递
WorkerThread->>WorkerThread: 执行任务
else 无空闲线程
CachedThreadPool->>CachedThreadPool: 创建新线程
Note over CachedThreadPool: 线程数可达Integer.MAX_VALUE
CachedThreadPool->>WorkerThread: 分配任务
WorkerThread->>WorkerThread: 执行任务
end
Note over WorkerThread: 60秒无任务则销毁
4.2.4 线程生命周期管理
// CachedThreadPool的线程管理机制
public class CachedThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
// 第一波任务:创建10个线程
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " executed by " +
Thread.currentThread().getName());
try {
Thread.sleep(100); // 短暂任务
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
Thread.sleep(70000); // 等待70秒,超过60秒keepAliveTime
// 第二波任务:线程已被回收,需要重新创建
for (int i = 10; i < 15; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " executed by " +
Thread.currentThread().getName());
});
}
executor.shutdown();
}
}
4.2.5 适用场景与风险
适用场景:
- 大量短期异步任务
- 任务执行时间短且不规律
- IO密集型任务
风险点:
// 潜在的线程爆炸风险
ExecutorService executor = Executors.newCachedThreadPool();
// 如果大量长时间任务同时提交
for (int i = 0; i < 10000; i++) {
executor.submit(() -> {
try {
Thread.sleep(60000); // 长时间任务
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 可能创建10000个线程,导致系统崩溃!
4.3 SingleThreadExecutor - 单线程执行器
4.3.1 源码分析
/**
* 创建单线程执行器
* @return 单线程执行器
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(
1, // corePoolSize = 1
1, // maximumPoolSize = 1
0L, // keepAliveTime = 0
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>() // 无界队列
)
);
}
// 支持自定义ThreadFactory的版本
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(
1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory
)
);
}
4.3.2 FinalizableDelegatedExecutorService包装器
/**
* 委托模式包装器,防止配置被修改
*/
static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
// 重写finalize方法,确保资源释放
protected void finalize() {
super.shutdown();
}
}
/**
* 委托执行器服务,隐藏ThreadPoolExecutor的配置方法
*/
static class DelegatedExecutorService extends AbstractExecutorService {
private final ExecutorService e;
DelegatedExecutorService(ExecutorService executor) {
e = executor;
}
// 只暴露ExecutorService接口方法
public void execute(Runnable command) { e.execute(command); }
public void shutdown() { e.shutdown(); }
public List<Runnable> shutdownNow() { return e.shutdownNow(); }
// ... 其他委托方法
// 不暴露ThreadPoolExecutor的配置方法,如setCorePoolSize等
}
4.3.3 执行特性
sequenceDiagram
participant Client
participant SingleThreadExecutor
participant WorkerThread
participant LinkedBlockingQueue
Client->>SingleThreadExecutor: submit(task1)
SingleThreadExecutor->>WorkerThread: 执行task1
Client->>SingleThreadExecutor: submit(task2)
SingleThreadExecutor->>LinkedBlockingQueue: task2入队
Client->>SingleThreadExecutor: submit(task3)
SingleThreadExecutor->>LinkedBlockingQueue: task3入队
WorkerThread->>WorkerThread: 完成task1
WorkerThread->>LinkedBlockingQueue: 获取task2
WorkerThread->>WorkerThread: 执行task2
WorkerThread->>WorkerThread: 完成task2
WorkerThread->>LinkedBlockingQueue: 获取task3
WorkerThread->>WorkerThread: 执行task3
Note over WorkerThread: 严格按顺序执行
4.3.5 与直接使用Thread的区别
// 直接使用Thread的问题
public class DirectThreadExample {
public static void main(String[] args) {
// 问题1:线程异常终止后无法自动恢复
Thread worker = new Thread(() -> {
while (true) {
// 处理任务
if (someCondition) {
throw new RuntimeException("线程异常终止");
// 线程死亡,后续任务无法执行
}
}
});
worker.start();
}
}
// SingleThreadExecutor的优势
public class SingleThreadExecutorExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
// 优势1:异常隔离,单个任务异常不影响后续任务
executor.submit(() -> {
throw new RuntimeException("任务1异常");
});
executor.submit(() -> {
System.out.println("任务2正常执行"); // 仍能正常执行
});
// 优势2:自动线程管理
// 如果工作线程因异常终止,会自动创建新线程
executor.shutdown();
}
}
4.3.6 适用场景
适用场景:
- 需要顺序执行的任务
- 状态敏感的操作
- 资源访问需要串行化
- 简单的后台任务处理
4.4 ScheduledThreadPool - 定时任务线程池
4.4.1 源码分析
/**
* 创建定时任务线程池
* @param corePoolSize 核心线程数
* @return 定时任务线程池
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
// 支持自定义ThreadFactory的版本
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
// 单线程定时任务执行器
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService(
new ScheduledThreadPoolExecutor(1)
);
}
4.4.2 ScheduledThreadPoolExecutor继承关系
classDiagram
class ThreadPoolExecutor {
+execute(Runnable)
+submit(Callable)
}
class ScheduledExecutorService {
<<interface>>
+schedule(Callable, long, TimeUnit)
+scheduleAtFixedRate(Runnable, long, long, TimeUnit)
+scheduleWithFixedDelay(Runnable, long, long, TimeUnit)
}
class ScheduledThreadPoolExecutor {
-DelayedWorkQueue workQueue
+schedule()
+scheduleAtFixedRate()
+scheduleWithFixedDelay()
}
ThreadPoolExecutor <|-- ScheduledThreadPoolExecutor
ScheduledExecutorService <|.. ScheduledThreadPoolExecutor
4.4.3 定时任务类型详解
// 1. 延迟执行(一次性)
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
// 2. 固定频率执行
ScheduledFuture<?> scheduleAtFixedRate(
Runnable command,
long initialDelay, // 初始延迟
long period, // 执行间隔
TimeUnit unit
)
// 3. 固定延迟执行
ScheduledFuture<?> scheduleWithFixedDelay(
Runnable command,
long initialDelay, // 初始延迟
long delay, // 执行完成后的延迟
TimeUnit unit
)
4.4.4 DelayedWorkQueue机制
flowchart TD
A["DelayedWorkQueue<br/>延迟工作队列"] --> B["优先级队列特性"]
A --> C["延迟调度特性"]
B --> D["基于二叉堆实现"]
B --> E["自动扩容机制"]
C --> F["按执行时间排序"]
C --> G["支持延迟获取"]
D --> H["最小堆结构<br/>最早执行的任务在堆顶"]
E --> I["初始容量16<br/>动态扩容至Integer.MAX_VALUE"]
F --> J["compareTo方法比较<br/>执行时间优先级"]
G --> K["take()方法会阻塞<br/>直到任务到期"]
H --> L["插入: O(log n)<br/>删除: O(log n)"]
I --> M["内存使用优化"]
J --> N["精确的时间调度"]
K --> O["高效的延迟执行"]
style A fill:#e3f2fd
style H fill:#c8e6c9
style L fill:#fff3e0
style N fill:#f3e5f5
4.4.5 定时任务执行流程
sequenceDiagram
participant Client
participant ScheduledThreadPoolExecutor
participant DelayedWorkQueue
participant WorkerThread
Client->>ScheduledThreadPoolExecutor: scheduleAtFixedRate(task, 0, 5, SECONDS)
ScheduledThreadPoolExecutor->>ScheduledThreadPoolExecutor: 创建ScheduledFutureTask
ScheduledThreadPoolExecutor->>DelayedWorkQueue: 添加任务
loop 定时执行
DelayedWorkQueue->>DelayedWorkQueue: 检查任务执行时间
DelayedWorkQueue->>WorkerThread: 取出到期任务
WorkerThread->>WorkerThread: 执行任务
WorkerThread->>ScheduledThreadPoolExecutor: 计算下次执行时间
ScheduledThreadPoolExecutor->>DelayedWorkQueue: 重新调度任务
end
4.4.6 scheduleAtFixedRate vs scheduleWithFixedDelay
public class SchedulingDifferenceDemo {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
// scheduleAtFixedRate:固定频率
// 如果任务执行时间 < 间隔时间,按固定间隔执行
// 如果任务执行时间 > 间隔时间,任务执行完立即开始下一次
executor.scheduleAtFixedRate(() -> {
System.out.println("FixedRate: " + new Date());
try {
Thread.sleep(3000); // 任务执行3秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, 0, 2, TimeUnit.SECONDS); // 间隔2秒
// scheduleWithFixedDelay:固定延迟
// 任务执行完成后,等待指定延迟时间再开始下一次
executor.scheduleWithFixedDelay(() -> {
System.out.println("FixedDelay: " + new Date());
try {
Thread.sleep(3000); // 任务执行3秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, 0, 2, TimeUnit.SECONDS); // 延迟2秒
}
}
gantt
title 定时任务执行对比
dateFormat X
axisFormat %s
section FixedRate(间隔2s,执行3s)
任务1 :active, task1, 0, 3
任务2 :active, task2, 3, 6
任务3 :active, task3, 6, 9
section FixedDelay(延迟2s,执行3s)
任务1 :active, task4, 0, 3
等待2s :task5, 3, 5
任务2 :active, task6, 5, 8
等待2s :task7, 8, 10
任务3 :active, task8, 10, 13
5. ThreadPoolExecutor核心机制
5.1 构造参数详解
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 线程存活时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 工作队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
)
5.2 线程池状态管理
// 线程池状态定义(使用AtomicInteger的高3位)
private static final int RUNNING = -1 << COUNT_BITS; // 111
private static final int SHUTDOWN = 0 << COUNT_BITS; // 000
private static final int STOP = 1 << COUNT_BITS; // 001
private static final int TIDYING = 2 << COUNT_BITS; // 010
private static final int TERMINATED = 3 << COUNT_BITS; // 011
stateDiagram-v2
[*] --> RUNNING : 创建线程池
RUNNING --> SHUTDOWN : shutdown()
RUNNING --> STOP : shutdownNow()
SHUTDOWN --> TIDYING : 队列为空且线程数为0
STOP --> TIDYING : 线程数为0
TIDYING --> TERMINATED : terminated()钩子方法完成
note right of RUNNING
接受新任务
处理队列中的任务
end note
note right of SHUTDOWN
不接受新任务
处理队列中的任务
end note
note right of STOP
不接受新任务
不处理队列中的任务
中断正在执行的任务
end note
5.3 任务执行流程
/**
* 任务执行的核心方法
*/
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get(); // 获取当前状态和线程数
// 步骤1:如果当前线程数 < 核心线程数,创建核心线程
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) // true表示创建核心线程
return;
c = ctl.get();
}
// 步骤2:如果线程池运行中且任务成功入队
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 双重检查:如果线程池已停止,移除任务并拒绝
if (!isRunning(recheck) && remove(command))
reject(command);
// 如果没有工作线程,创建一个
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 步骤3:尝试创建非核心线程,失败则拒绝任务
else if (!addWorker(command, false))
reject(command);
}
flowchart TD
A["execute(Runnable command)"] --> B{"workerCountOf(c) < corePoolSize?"}
B -->|是| C["addWorker(command, true)<br/>创建核心线程"]
B -->|否| D{"isRunning(c) && workQueue.offer(command)?"}
C --> C1{"addWorker成功?"}
C1 -->|是| E["任务执行完成"]
C1 -->|否| D
D -->|是| F["任务成功入队"]
D -->|否| G["addWorker(command, false)<br/>创建非核心线程"]
F --> H{"双重检查: isRunning(recheck)?"}
H -->|否| I["remove(command) && reject(command)"]
H -->|是| J{"workerCountOf(recheck) == 0?"}
J -->|是| K["addWorker(null, false)<br/>确保有线程处理队列"]
J -->|否| E
G --> G1{"addWorker成功?"}
G1 -->|是| E
G1 -->|否| L["reject(command)<br/>执行拒绝策略"]
I --> M["任务被拒绝"]
K --> E
L --> M
style A fill:#e1f5fe
style C fill:#c8e6c9
style F fill:#fff3e0
style G fill:#f3e5f5
style L fill:#ffcdd2
style M fill:#ffcdd2
5.4 Worker内部类源码分析
/**
* Worker类是ThreadPoolExecutor的核心内部类
* 继承AbstractQueuedSynchronizer实现独占锁
* 实现Runnable接口作为线程执行体
*/
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
private static final long serialVersionUID = 6138294804551838833L;
/** 执行任务的线程,由ThreadFactory创建 */
final Thread thread;
/** 初始任务,可能为null */
Runnable firstTask;
/** 完成任务计数器 */
volatile long completedTasks;
/**
* 构造方法
* @param firstTask 第一个任务,可以为null
*/
Worker(Runnable firstTask) {
setState(-1); // 禁止中断直到runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); // 创建线程
}
/** 委托给外部类的runWorker方法 */
public void run() {
runWorker(this);
}
// 锁方法实现
protected boolean isHeldExclusively() {
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
/**
* 中断线程(如果已启动)
*/
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
5.5 addWorker方法源码分析
/**
* 添加工作线程
* @param firstTask 新线程的第一个任务,可以为null
* @param core 是否为核心线程
* @return 是否成功创建并启动线程
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (int c = ctl.get();;) {
// 检查线程池状态
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP)
|| firstTask != null
|| workQueue.isEmpty()))
return false;
for (;;) {
// 检查线程数量限制
if (workerCountOf(c)
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
return false;
// CAS增加工作线程计数
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // 重新读取ctl
if (runStateAtLeast(c, SHUTDOWN))
continue retry;
// CAS失败,重试内层循环
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask); // 创建Worker
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock(); // 获取主锁
try {
// 持有锁时重新检查状态
int c = ctl.get();
if (isRunning(c) ||
(runStateLessThan(c, STOP) && firstTask == null)) {
if (t.getState() != Thread.State.NEW)
throw new IllegalThreadStateException();
workers.add(w); // 添加到工作线程集合
workerAdded = true;
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s; // 更新最大线程数记录
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start(); // 启动线程
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w); // 启动失败的清理工作
}
return workerStarted;
}
5.6 runWorker方法源码分析
/**
* 工作线程的主循环
* @param w Worker实例
*/
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // 允许中断(state从-1变为0)
boolean completedAbruptly = true;
try {
// 循环获取并执行任务
while (task != null || (task = getTask()) != null) {
w.lock(); // 获取独占锁
// 如果线程池正在停止,确保线程被中断
// 如果没有,确保线程不被中断
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task); // 执行前钩子
try {
task.run(); // 执行任务
afterExecute(task, null); // 执行后钩子
} catch (RuntimeException x) {
afterExecute(task, x);
throw x;
} catch (Error x) {
afterExecute(task, x);
throw x;
} catch (Throwable x) {
afterExecute(task, x);
throw new Error(x);
}
} finally {
task = null;
w.completedTasks++; // 增加完成任务计数
w.unlock(); // 释放锁
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly); // 处理工作线程退出
}
}
5.7 getTask方法源码分析
/**
* 从工作队列获取任务
* @return 任务或null(表示线程应该退出)
*/
private Runnable getTask() {
boolean timedOut = false; // 上次poll是否超时
for (;;) {
int c = ctl.get();
// 检查队列是否为空(仅在必要时)
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// 工作线程是否需要超时淘汰?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
5.8 ThreadFactory源码分析
/**
* 默认线程工厂实现
*/
private static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false); // 设置为非守护线程
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY); // 设置为正常优先级
return t;
}
}
5.9 拒绝策略
// 1. AbortPolicy(默认):抛出异常
public static class AbortPolicy implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException(
"Task " + r.toString() + " rejected from " + e.toString());
}
}
// 2. CallerRunsPolicy:调用者线程执行
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run(); // 在调用者线程中执行
}
}
}
// 3. DiscardPolicy:静默丢弃
public static class DiscardPolicy implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 什么都不做,静默丢弃
}
}
// 4. DiscardOldestPolicy:丢弃最老的任务
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll(); // 移除队首任务
e.execute(r); // 重新提交当前任务
}
}
}
6. 线程池参数计算与调优
6.1 核心线程数计算公式
6.1.1 CPU密集型任务
/**
* CPU密集型任务的核心线程数计算
* 公式:核心线程数 = CPU核心数 + 1
* 原因:CPU密集型任务主要消耗CPU资源,过多线程会导致上下文切换开销
*/
public class CPUIntensiveThreadPoolConfig {
public static int calculateCorePoolSize() {
int cpuCores = Runtime.getRuntime().availableProcessors();
return cpuCores + 1;
}
public static ExecutorService createCPUIntensivePool() {
int corePoolSize = calculateCorePoolSize();
return new ThreadPoolExecutor(
corePoolSize,
corePoolSize, // 最大线程数等于核心线程数
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(100), // 有界队列防止OOM
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
}
}
6.1.2 IO密集型任务
/**
* IO密集型任务的线程数计算
* 公式:线程数 = CPU核心数 × (1 + IO等待时间/CPU计算时间)
* 或者:线程数 = CPU核心数 / (1 - 阻塞系数)
* 阻塞系数 = 阻塞时间 / (阻塞时间 + 计算时间)
*/
public class IOIntensiveThreadPoolConfig {
/**
* 根据阻塞系数计算线程数
* @param blockingCoefficient 阻塞系数(0-1之间)
* @return 推荐线程数
*/
public static int calculateThreadsByBlockingCoefficient(double blockingCoefficient) {
int cpuCores = Runtime.getRuntime().availableProcessors();
return (int) (cpuCores / (1 - blockingCoefficient));
}
/**
* 根据IO等待时间比例计算线程数
* @param ioWaitTime IO等待时间(毫秒)
* @param cpuTime CPU计算时间(毫秒)
* @return 推荐线程数
*/
public static int calculateThreadsByIOWaitRatio(long ioWaitTime, long cpuTime) {
int cpuCores = Runtime.getRuntime().availableProcessors();
return (int) (cpuCores * (1 + (double) ioWaitTime / cpuTime));
}
public static ExecutorService createIOIntensivePool() {
// 假设阻塞系数为0.8(80%时间在等待IO)
int corePoolSize = calculateThreadsByBlockingCoefficient(0.8);
int maximumPoolSize = corePoolSize * 2; // 最大线程数为核心线程数的2倍
return new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(200),
new ThreadPoolExecutor.CallerRunsPolicy()
);
}
}
总结
通过对Java四种默认线程池的深入分析,我们可以看到:
- FixedThreadPool:适合CPU密集型任务,但要注意队列容量控制
- CachedThreadPool:适合大量短期异步任务,但要防止线程爆炸
- SingleThreadExecutor:保证任务顺序执行,提供异常恢复能力
- ScheduledThreadPool:支持定时和周期性任务,基于优先级队列实现
在实际应用中,建议根据具体场景自定义线程池参数,避免使用默认的无界队列,并做好监控和异常处理。理解线程池的内部机制有助于我们更好地进行性能调优和问题诊断。