0
点赞
收藏
分享

微信扫一扫

ExecutorService 线程池详解

🧵 ExecutorService 线程池详解

1️⃣ 什么是 ExecutorService?

  • 定义ExecutorService 是 Java 线程池的顶层接口,用于管理和控制线程的执行
  • 作用
  1. 线程复用,避免频繁创建/销毁线程
  2. 任务提交与调度,支持批量、定时任务
  3. 统一管理,可优雅关闭线程池
  • 核心特点
  • 提交任务(Runnable/Callable)
  • 获取任务执行结果(Future)
  • 支持线程池生命周期管理(shutdown/shutdownNow)

2️⃣ 常用实现类

类名

描述

ThreadPoolExecutor

核心线程数、最大线程数、队列、拒绝策略可自定义

ScheduledThreadPoolExecutor

支持定时任务和周期任务

ForkJoinPool

支持分治任务并行(Java 7+)

通过 Executors 工具类快速创建线程池。

3️⃣ 创建线程池方式(Executors 工具类)

import java.util.concurrent.*;

 

public class ThreadPoolDemo {

public static void main(String[] args) {

// 1. 固定线程池

ExecutorService fixedPool = Executors.newFixedThreadPool(5);

 

// 2. 单线程池

ExecutorService singlePool = Executors.newSingleThreadExecutor();

 

// 3. 缓存线程池(按需创建)

ExecutorService cachedPool = Executors.newCachedThreadPool();

 

// 4. 定时线程池

ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);

}

}

4️⃣ 提交任务方式

4.1 使用 Runnable(无返回值)

ExecutorService pool = Executors.newFixedThreadPool(3);

 

pool.submit(() -> {

System.out.println(Thread.currentThread().getName() + " 执行任务");

});

4.2 使用 Callable(有返回值)

Callable<Integer> task = () -> {

Thread.sleep(1000);

return 123;

};

 

Future<Integer> future = pool.submit(task);

System.out.println("任务结果: " + future.get());

4.3 批量任务执行

List<Callable<String>> tasks = Arrays.asList(

() -> "任务1",

() -> "任务2",

() -> "任务3"

);

 

List<Future<String>> results = pool.invokeAll(tasks);

for (Future<String> f : results) {

System.out.println(f.get());

}

5️⃣ 线程池关闭方法

方法

作用

shutdown()

等待已提交任务执行完成,再关闭线程池

shutdownNow()

尝试立即停止任务,返回未执行的任务列表

awaitTermination(timeout, unit)

等待线程池关闭完成,超时返回

pool.shutdown();

try {

if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {

pool.shutdownNow();

}

} catch (InterruptedException e) {

pool.shutdownNow();

}

6️⃣ ThreadPoolExecutor 核心参数详解

ThreadPoolExecutor pool = new ThreadPoolExecutor(

5,                      // corePoolSize: 核心线程数

10,                     // maximumPoolSize: 最大线程数

60,                     // keepAliveTime: 非核心线程空闲存活时间

TimeUnit.SECONDS,       // 时间单位

new LinkedBlockingQueue<>(100), // 阻塞队列

Executors.defaultThreadFactory(),

new ThreadPoolExecutor.AbortPolicy() // 拒绝策略

);

  • 核心线程数 corePoolSize:线程池维护的最少线程数
  • 最大线程数 maximumPoolSize:线程池允许的最大线程数
  • 阻塞队列:保存待执行任务
  • 拒绝策略
  • AbortPolicy:直接抛异常
  • DiscardPolicy:丢弃任务
  • DiscardOldestPolicy:丢弃最早任务
  • CallerRunsPolicy:由调用者线程执行

7️⃣ 高级特性

  1. 定时任务

ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);

scheduledPool.scheduleAtFixedRate(() -> System.out.println("执行任务"), 0, 2, TimeUnit.SECONDS);

  1. ForkJoinPool(适合分治任务):

ForkJoinPool forkJoinPool = new ForkJoinPool();

  1. 任务取消

Future<?> f = pool.submit(task);

f.cancel(true); // 中断任务

8️⃣ 注意事项

  • 避免使用 Executors.newFixedThreadPool() / newCachedThreadPool() 创建无界队列的线程池用于高并发生产环境,容易 OOM
  • 对任务执行时间较长或数量庞大,建议使用 自定义 ThreadPoolExecutor + 有界队列 + 拒绝策略
  • 使用完线程池必须 shutdown,否则 JVM 无法退出
  • 多线程共享数据需注意 线程安全

💡 总结

  • ExecutorService 提供 统一线程池管理接口
  • 支持 Runnable / Callable / Future
  • 核心优势:
  1. 避免频繁创建线程
  2. 可控制线程数量、队列长度
  3. 支持定时、周期任务
  4. 可安全关闭、回收资源

https://www.52runoob.com/archives/6475

举报

相关推荐

0 条评论