🧵 ExecutorService 线程池详解
1️⃣ 什么是 ExecutorService?
- 定义:
ExecutorService
是 Java 线程池的顶层接口,用于管理和控制线程的执行 - 作用:
- 线程复用,避免频繁创建/销毁线程
- 任务提交与调度,支持批量、定时任务
- 统一管理,可优雅关闭线程池
- 提交任务(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) {
|
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
|
ExecutorService singlePool = Executors.newSingleThreadExecutor();
|
ExecutorService cachedPool = Executors.newCachedThreadPool();
|
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
|
4️⃣ 提交任务方式
4.1 使用 Runnable(无返回值)
ExecutorService pool = Executors.newFixedThreadPool(3);
|
System.out.println(Thread.currentThread().getName() + " 执行任务");
|
4.2 使用 Callable(有返回值)
Callable<Integer> task = () -> {
|
Future<Integer> future = pool.submit(task);
|
System.out.println("任务结果: " + future.get());
|
4.3 批量任务执行
List<Callable<String>> tasks = Arrays.asList(
|
List<Future<String>> results = pool.invokeAll(tasks);
|
for (Future<String> f : results) {
|
System.out.println(f.get());
|
5️⃣ 线程池关闭方法
方法
| 作用
|
shutdown()
| 等待已提交任务执行完成,再关闭线程池
|
shutdownNow()
| 尝试立即停止任务,返回未执行的任务列表
|
awaitTermination(timeout, unit)
| 等待线程池关闭完成,超时返回
|
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
|
} catch (InterruptedException e) {
|
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️⃣ 高级特性
- 定时任务:
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);
|
scheduledPool.scheduleAtFixedRate(() -> System.out.println("执行任务"), 0, 2, TimeUnit.SECONDS);
|
- ForkJoinPool(适合分治任务):
ForkJoinPool forkJoinPool = new ForkJoinPool();
|
- 任务取消:
Future<?> f = pool.submit(task);
|
8️⃣ 注意事项
- 避免使用
Executors.newFixedThreadPool()
/ newCachedThreadPool()
创建无界队列的线程池用于高并发生产环境,容易 OOM - 对任务执行时间较长或数量庞大,建议使用 自定义 ThreadPoolExecutor + 有界队列 + 拒绝策略
- 使用完线程池必须 shutdown,否则 JVM 无法退出
- 多线程共享数据需注意 线程安全
💡 总结
ExecutorService
提供 统一线程池管理接口- 支持 Runnable / Callable / Future
- 核心优势:
- 避免频繁创建线程
- 可控制线程数量、队列长度
- 支持定时、周期任务
- 可安全关闭、回收资源
https://www.52runoob.com/archives/6475