一、阻塞队列是什么?
阻塞队列就是线程池的 "候客区"。当核心线程全部忙碌,新进来的任务会进入队列等待。
Java 提供了多种阻塞队列,线程池最常用 4 种:
1. ArrayBlockingQueue
- 基于数组实现
- 有界队列
- 必须指定容量
- 生产环境最推荐
2. LinkedBlockingQueue
- 基于链表
- 可无界、可有界
- 无界会导致任务无限堆积 → OOM
3. SynchronousQueue
- 不存储元素
- 直接移交任务
- 任务量大容易疯狂创建线程
4. PriorityBlockingQueue
- 支持优先级
- 无界队列
- 按优先级执行任务
二、生产环境队列选择原则
- 必须使用有界队列
- 优先选择 ArrayBlockingQueue
- 禁止使用无界队列
- 队列长度根据业务压力调整
三、拒绝策略详解
当队列满 + 线程数达到最大 → 触发拒绝策略。JDK 提供 4 种拒绝策略:
1. AbortPolicy(默认)
直接抛出 RejectedExecutionException。不建议生产使用,会导致任务丢失。
2. CallerRunsPolicy(生产最推荐)
任务回退到调用者线程执行。不丢任务、不崩溃、起到限流作用。
3. DiscardOldestPolicy
丢弃队列最老的任务,再尝试提交。
4. DiscardPolicy
直接丢弃任务,不抛异常。
四、生产环境拒绝策略选择
- 高可靠业务:CallerRunsPolicy
- 允许丢任务:DiscardPolicy
- 测试环境:AbortPolicy
- 特殊场景:自定义拒绝策略
五、自定义拒绝策略示例
public class MyRejectPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
System.out.println("任务被拒绝,记录日志 + 告警");
}
}