Executors
工厂类,如Executors.newFixedThreadPool(int nThreads)
创建固定大小线程池,也可直接使用ThreadPoolExecutor
构造函数自定义核心参数(核心线程数、最大线程数、存活时间等),需注意任务队列选择与资源关闭管理。线程池的核心优势
- 降低资源开销:复用已创建的线程,避免频繁线程创建/销毁。
- 提高响应速度:任务到达时直接使用空闲线程执行。
- 任务统一管理:支持任务队列、拒绝策略等机制。
创建线程池的两种方式
方式1:通过 Executors
工厂类(快速创建)
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; // 创建固定大小的线程池(推荐常规使用) ExecutorService fixedPool = Executors.newFixedThreadPool(5); // 创建可缓存线程池(适合短时异步任务) ExecutorService cachedPool = Executors.newCachedThreadPool(); // 创建单线程池(保证任务顺序执行) ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); // 创建定时任务线程池 ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
方式2:通过 ThreadPoolExecutor
构造函数(精细控制)
import java.util.concurrent.*; ExecutorService customPool = new ThreadPoolExecutor( 5, // 核心线程数 (corePoolSize) 10, // 最大线程数 (maximumPoolSize) 60L, // 空闲线程存活时间 (keepAliveTime) TimeUnit.SECONDS, // 时间单位 new ArrayBlockingQueue<>(100), // 任务队列 (容量100) Executors.defaultThreadFactory(), // 线程工厂 new ThreadPoolExecutor.AbortPolicy() // 拒绝策略 );
关键参数详解
参数 | 说明 |
---|---|
corePoolSize |
核心线程数(即使空闲也不会被回收) |
maximumPoolSize |
最大线程数(当队列满时创建新线程,直到达到此值) |
keepAliveTime |
非核心线程的空闲存活时间(超时后回收) |
workQueue |
任务队列(推荐有界队列如 ArrayBlockingQueue ,避免OOM) |
handler |
拒绝策略(当线程和队列都满时的处理方式) |
四种拒绝策略对比
策略 | 行为 |
---|---|
AbortPolicy (默认) |
抛出 RejectedExecutionException 异常 |
CallerRunsPolicy |
由提交任务的线程直接执行任务 |
DiscardPolicy |
静默丢弃新任务,不报错 |
DiscardOldestPolicy |
丢弃队列中最旧的任务,尝试重新提交新任务 |
使用示例
// 提交任务到线程池 customPool.execute(() -> { System.out.println("Task running by " + Thread.currentThread().getName()); }); // 关闭线程池(需在程序结束时调用) customPool.shutdown(); // 温和关闭(等待执行中的任务) // customPool.shutdownNow(); // 立即关闭(尝试中断所有任务)
最佳实践与注意事项
-
避免使用无界队列
Executors.newFixedThreadPool()
默认使用无界队列LinkedBlockingQueue
,可能导致OOM,推荐:new ThreadPoolExecutor(n, n, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100));
-
合理设置线程数量
- CPU密集型任务:核心数 = CPU核数 + 1
- I/O密集型任务:核心数 = CPU核数 × 2
-
务必关闭线程池
使用shutdown()
或shutdownNow()
防止资源泄漏。 -
监控线程池状态
通过ThreadPoolExecutor
的方法获取运行状态:customPool.getActiveCount(); // 活动线程数 customPool.getCompletedTaskCount(); // 已完成任务数
- 简单场景:用
Executors
快速创建(注意无界队列风险)。 - 生产环境:优先选择
ThreadPoolExecutor
自定义参数。 - 关键原则:设置合理线程数、使用有界队列、明确拒绝策略、及时关闭线程池。
引用说明参考 Oracle 官方文档 ThreadPoolExecutor 及《Java并发编程实战》(Brian Goetz 著),遵循阿里巴巴Java开发手册的线程池规约。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/30277.html