适合人群:Java中级开发者 | 并发编程入门者 | 系统调优实践者
目录
一、引言:为什么线程池是Java并发的核心?
二、线程池核心知识点详解
1. 线程池核心参数与原理
2. 线程池的创建与使用
(1) 基础用法示例
(2) 内置线程池的隐患
3. 线程池调优与注意事项
(1) 参数配置原则
(2) 监控线程池状态
(3) 合理选择拒绝策略
三、进一步学习方向
一、引言:为什么线程池是Java并发的核心?
在高并发场景下,频繁创建和销毁线程会带来巨大开销(如内存抖动、GC压力)。线程池通过复用线程和资源管控解决了以下问题:
-
降低资源消耗:避免线程频繁创建/销毁的开销
-
提升响应速度:任务到达时直接复用空闲线程
-
增强可控性:统一管理线程数量、任务队列、拒绝策略
二、线程池核心知识点详解
1. 线程池核心参数与原理
Java线程池通过ThreadPoolExecutor
实现,其构造函数包含7个关键参数:
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数(长期保留的线程)
int maximumPoolSize, // 最大线程数(临时线程=最大-核心)
long keepAliveTime, // 临时线程空闲存活时间
TimeUnit unit, // 存活时间单位(秒/毫秒等)
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程创建工厂
RejectedExecutionHandler handler // 拒绝策略
)
线程池工作流程:
-
提交任务时,优先使用核心线程执行
-
核心线程满后,任务进入阻塞队列
-
队列满后,创建临时线程(不超过
maximumPoolSize
) -
线程和队列均满时,触发拒绝策略
2. 线程池的创建与使用
(1) 基础用法示例
import java.util.concurrent.*;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // corePoolSize
4, // maximumPoolSize
30, // keepAliveTime
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(10), // 任务队列容量10
Executors.defaultThreadFactory(), // 默认线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略:直接抛出异常
);
// 提交10个任务
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.execute(() -> {
try {
System.out.println(
"线程" + Thread.currentThread().getName() +
"执行任务" + taskId
);
Thread.sleep(1000); // 模拟任务耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池(非阻塞,等待所有任务完成)
executor.shutdown();
}
}
输出分析:
-
核心线程2个,处理前2个任务
-
后续任务进入队列,队列容量10,最终4个线程处理10个任务
(2) 内置线程池的隐患
Executors
工具类提供了快速创建线程池的方法,但存在风险:
// 可能导致OOM(队列无界)
ExecutorService cachedPool = Executors.newCachedThreadPool();
ExecutorService fixedPool = Executors.newFixedThreadPool(10);
// 推荐手动创建线程池,明确参数!
3. 线程池调优与注意事项
(1) 参数配置原则
-
CPU密集型任务:
-
corePoolSize
= CPU核心数 + 1 -
队列选择有界队列(如
ArrayBlockingQueue
)
-
-
IO密集型任务:
-
corePoolSize
= 2 * CPU核心数 -
队列容量适当增大
-
(2) 监控线程池状态
// 定期打印线程池状态
ScheduledExecutorService monitor = Executors.newScheduledThreadPool(1);
monitor.scheduleAtFixedRate(() -> {
System.out.println("活跃线程数:" + executor.getActiveCount());
System.out.println("队列任务数:" + executor.getQueue().size());
}, 0, 1, TimeUnit.SECONDS);
(3) 合理选择拒绝策略
策略类 | 行为 |
---|---|
AbortPolicy (默认) | 抛出RejectedExecutionException |
CallerRunsPolicy | 由提交任务的线程直接执行 |
DiscardOldestPolicy | 丢弃队列中最旧的任务并重试 |
DiscardPolicy | 静默丢弃新任务 |
三、进一步学习方向
-
并发工具类:
-
CountDownLatch
:多线程任务同步 -
CompletableFuture
:异步编程模型
-
-
性能优化:
-
使用
ThreadLocal
避免线程间数据竞争 -
分析线程转储(Thread Dump)排查死锁
-
-
框架集成:
-
Spring的
@Async
注解实现异步任务 -
分布式线程池(如Dubbo的线程模型)
-