全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-10 10 分钟 ✍️ juanwangdev

程池

程池复用线程,避免频繁创建销毁,提高性能和资源利用率。

Executors 工厂方法

Java
// 固定大小线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(5);

// 缓存线程池(按需创建,空闲回收)
ExecutorService cachedPool = Executors.newCachedThreadPool();

// 单线程池(顺序执行)
ExecutorService singlePool = Executors.newSingleThreadExecutor();

// 定时任务线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);

Executors 问题:生产环境不建议直接用 Executors,FixedThreadPool 和 SingleThreadExecutor 任务队列无界可能导致 OOM。

ThreadPoolExecutor 核心参数

Java
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    corePoolSize,           // 核心线程数(常驻)
    maximumPoolSize,        // 最大线程数
    keepAliveTime,          // 非核心线程空闲存活时间
    TimeUnit.SECONDS,       // 时间单位
    workQueue,              // 任务队列
    threadFactory,          // 程工厂(可选)
    handler                 // 拒绝策略(可选)
);

参数详解

参数说明
corePoolSize核心线程数,常驻不回收
maximumPoolSize最大线程数,任务多时临时扩展
keepAliveTime非核心线程空闲存活时间
workQueue任务队列,等待执行的任务
handler拒绝策略,队列满时处理新任务

任务队列类型

队列类型特点
ArrayBlockingQueue有界队列,防止 OOM
LinkedBlockingQueue可选有界,默认无界
SynchronousQueue无缓冲,直接传递

拒绝策略

策略说明
AbortPolicy抛 RejectedExecutionException(默认)
CallerRunsPolicy由调用线程执行
DiscardPolicy直接丢弃
DiscardOldestPolicy丢弃最老任务,尝试重新提交

程池执行流程

Java
提交任务 → 核心线程数未满? → 创建核心线程执行
              ↓ 满
         加入任务队列 → 队列未满? → 等待核心线程执行
              ↓ 满
         创建非核心线程 → 未达最大? → 执行任务
              ↓ 达到最大
         执行拒绝策略

推荐配置

Java
// 生产环境推荐配置
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                              // 核心 5 个
    10,                             // 最大 10 个
    60, TimeUnit.SECONDS,           // 空闲 60 秒回收
    new ArrayBlockingQueue<>(100),  // 有界队列,容量 100
    Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.AbortPolicy()
);

配置原则

  • CPU 密集型:核心线程数 ≈ CPU 核数 + 1
  • IO 密集型:核心线程数 ≈ CPU 核数 × 2
  • 有界队列:防止任务堆积导致 OOM
  • 合理拒绝策略:记录日志或降级处理

程池使用示例

submit 提交任务

Java
executor.submit(() -> {
    // 执行任务
});

// submit 返回 Future,可获取结果
Future<String> future = executor.submit(() -> "结果");
String result = future.get();

execute 提交任务

Java
executor.execute(() -> {
    // 执行任务,无返回值
});

批量提交

Java
List<Callable<String>> tasks = Arrays.asList(
    () -> "task1",
    () -> "task2",
    () -> "task3"
);

List<Future<String>> futures = executor.invokeAll(tasks);
for (Future<String> future : futures) {
    System.out.println(future.get());
}

程池关闭

Java
// 平滑关闭:不再接受新任务,等待现有任务完成
executor.shutdown();

// 立即关闭:尝试中断所有任务
List<Runnable> unfinished = executor.shutdownNow();

// 等待关闭完成
executor.awaitTermination(60, TimeUnit.SECONDS);

// 判断状态
executor.isShutdown();      // 是否已调用 shutdown
executor.isTerminated();    // 是否所有任务已完成

ScheduledExecutorService 定时任务

text
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

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

// 固定延迟(任务完成后延迟 n 秒再执行)
scheduler.scheduleWithFixedDelay(() -> {
    System.out.println("执行");
}, 0, 3, TimeUnit.SECONDS);

// 固定频率(不管任务是否完成,每隔 n 秒执行)
scheduler.scheduleAtFixedRate(() -> {
    System.out.println("执行");
}, 0, 3, TimeUnit.SECONDS);

要点总结

  • 程池复用线程,避免创建销毁开销
  • 生产环境不建议直接用 Executors
  • 核心参数:corePoolSize、maximumPoolSize、workQueue、handler
  • CPU 密集型:线程数 ≈ CPU核数 + 1
  • IO 密集型:线程数 ≈ CPU核数 × 2
  • 必须使用有界队列防止 OOM
  • shutdown() 平滑关闭,shutdownNow() 立即关闭
  • ScheduledExecutorService 执行定时任务

📝 发现内容有误?点击此处直接编辑

← 上一篇 程同步与锁
下一篇 → 程的创建与启动
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库