Java线程池 #

一、线程池概述 #

1.1 为什么使用线程池 #

  • 减少线程创建销毁开销
  • 控制并发数量
  • 提供任务队列和拒绝策略
  • 便于管理线程

1.2 线程池体系 #

text
Executor
└── ExecutorService
    ├── ThreadPoolExecutor
    │   └── ScheduledThreadPoolExecutor
    └── ForkJoinPool

二、ThreadPoolExecutor #

2.1 创建线程池 #

java
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                              // 核心线程数
    10,                             // 最大线程数
    60L,                            // 空闲线程存活时间
    TimeUnit.SECONDS,               // 时间单位
    new ArrayBlockingQueue<>(100),  // 任务队列
    Executors.defaultThreadFactory(),  // 线程工厂
    new ThreadPoolExecutor.AbortPolicy()  // 拒绝策略
);

2.2 参数详解 #

参数 说明
corePoolSize 核心线程数,常驻线程
maximumPoolSize 最大线程数
keepAliveTime 空闲线程存活时间
unit 时间单位
workQueue 任务队列
threadFactory 线程工厂
handler 拒绝策略

2.3 执行流程 #

text
1. 线程数 < corePoolSize → 创建新线程
2. 线程数 = corePoolSize → 加入队列
3. 队列满 → 创建新线程直到maximumPoolSize
4. 线程数 = maximumPoolSize → 执行拒绝策略

2.4 拒绝策略 #

java
// AbortPolicy:抛异常(默认)
new ThreadPoolExecutor.AbortPolicy();

// CallerRunsPolicy:调用者执行
new ThreadPoolExecutor.CallerRunsPolicy();

// DiscardPolicy:丢弃任务
new ThreadPoolExecutor.DiscardPolicy();

// DiscardOldestPolicy:丢弃最老任务
new ThreadPoolExecutor.DiscardOldestPolicy();

三、Executors工厂方法 #

3.1 FixedThreadPool #

java
ExecutorService executor = Executors.newFixedThreadPool(5);

// 固定线程数,无界队列
// corePoolSize = maximumPoolSize = n

3.2 CachedThreadPool #

java
ExecutorService executor = Executors.newCachedThreadPool();

// 可缓存线程池,线程数无限
// corePoolSize = 0, maximumPoolSize = Integer.MAX_VALUE

3.3 SingleThreadExecutor #

java
ExecutorService executor = Executors.newSingleThreadExecutor();

// 单线程执行器
// corePoolSize = maximumPoolSize = 1

3.4 ScheduledThreadPool #

java
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);

// 延迟执行
scheduler.schedule(() -> {
    System.out.println("延迟1秒执行");
}, 1, TimeUnit.SECONDS);

// 定期执行
scheduler.scheduleAtFixedRate(() -> {
    System.out.println("每2秒执行");
}, 0, 2, TimeUnit.SECONDS);

3.5 注意事项 #

java
// 不推荐使用Executors创建线程池
// 1. FixedThreadPool和SingleThreadExecutor使用无界队列,可能OOM
// 2. CachedThreadPool线程数无限,可能OOM

// 推荐:手动创建ThreadPoolExecutor
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5, 10, 60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(1000)
);

四、提交任务 #

4.1 execute #

java
executor.execute(() -> {
    System.out.println("执行任务");
});

4.2 submit #

java
Future<?> future1 = executor.submit(() -> {
    System.out.println("执行任务");
});

Future<Integer> future2 = executor.submit(() -> {
    return 100;
});

try {
    Integer result = future2.get();
    System.out.println(result);
} catch (Exception e) {
    e.printStackTrace();
}

4.3 invokeAll #

java
List<Callable<Integer>> tasks = Arrays.asList(
    () -> 1,
    () -> 2,
    () -> 3
);

List<Future<Integer>> futures = executor.invokeAll(tasks);

4.4 invokeAny #

java
Integer result = executor.invokeAny(tasks);  // 返回第一个完成的结果

五、关闭线程池 #

5.1 shutdown #

java
executor.shutdown();  // 平滑关闭,等待任务完成

if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
    executor.shutdownNow();  // 强制关闭
}

5.2 shutdownNow #

java
List<Runnable> notExecuted = executor.shutdownNow();  // 立即关闭
// 返回未执行的任务列表

5.3 判断状态 #

java
executor.isShutdown();     // 是否已关闭
executor.isTerminated();   // 是否已终止

六、线程池监控 #

java
ThreadPoolExecutor executor = new ThreadPoolExecutor(...);

// 监控信息
executor.getActiveCount();      // 活动线程数
executor.getCompletedTaskCount();  // 已完成任务数
executor.getQueue().size();     // 队列大小
executor.getPoolSize();         // 当前线程数
executor.getCorePoolSize();     // 核心线程数
executor.getMaximumPoolSize();  // 最大线程数

七、线程池配置建议 #

7.1 CPU密集型 #

java
// CPU核心数 + 1
int cores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    cores + 1, cores + 1, 0L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>()
);

7.2 IO密集型 #

java
// CPU核心数 * 2
int cores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    cores * 2, cores * 2, 60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>()
);

7.3 混合型 #

根据IO等待时间占比调整。

八、总结 #

线程池 特点
FixedThreadPool 固定线程数
CachedThreadPool 可缓存,线程数无限
SingleThreadExecutor 单线程
ScheduledThreadPool 支持定时任务

线程池要点:

  • 推荐手动创建ThreadPoolExecutor
  • 合理配置核心线程数和最大线程数
  • 选择合适的任务队列
  • 正确关闭线程池
最后更新:2026-03-26