JUC并发编程 线程池

66 阅读11分钟

线程池

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 线程池核心优势

  1. 线程复用:避免频繁创建销毁线程的开销
  2. 资源控制:限制并发线程数量,防止资源耗尽
  3. 任务管理:提供任务队列,支持异步执行
  4. 统一管理:集中管理线程生命周期

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四种默认线程池的深入分析,我们可以看到:

  1. FixedThreadPool:适合CPU密集型任务,但要注意队列容量控制
  2. CachedThreadPool:适合大量短期异步任务,但要防止线程爆炸
  3. SingleThreadExecutor:保证任务顺序执行,提供异常恢复能力
  4. ScheduledThreadPool:支持定时和周期性任务,基于优先级队列实现

在实际应用中,建议根据具体场景自定义线程池参数,避免使用默认的无界队列,并做好监控和异常处理。理解线程池的内部机制有助于我们更好地进行性能调优和问题诊断。