java线程池中阻塞队列已满 但是提供者还有任务下发怎么办
时间: 2025-06-29 09:02:41 浏览: 12
### Java 线程池阻塞队列满时的任务处理
当Java线程池中的阻塞队列已满而又有新的任务提交给线程池时,线程池会依据预先设定的饱和策略来决定如何处理这些额外的任务。具体来说:
- 如果当前活动线程数小于`maximumPoolSize`,即使阻塞队列已经满了,线程池也会创建一个新的工作线程来执行新来的任务[^2]。
然而,在所有可能的工作线程都已经启动并且阻塞队列也已经被填满的情况下,线程池将会触发其配置好的拒绝策略来进行最后的处理。常见的几种拒绝策略如下所示:
#### 拒绝策略选项
1. **AbortPolicy**: 这是最常用的默认策略;一旦发生拒绝事件,该策略将抛出一个未经检查的`RejectedExecutionException`异常。
2. **CallerRunsPolicy**: 当某个任务无法加入到线程池中时,此政策会让调用者的主线程自己运行这个任务。这可以减缓新任务的到来速度,从而缓解压力。
3. **DiscardOldestPolicy**: 此策略会选择丢弃最旧的一个请求以便腾出空间给最新到达的任务。请注意,“最老”的定义是指最早进入队列的那个任务。
4. **DiscardPolicy**: 直接静默地抛弃掉那些未能成功放入队列的新任务而不做任何通知或记录。
为了更好地理解这一点,下面给出了一段简单的代码示例展示了如何自定义线程池及其对应的拒绝策略:
```java
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) throws InterruptedException {
// 创建具有固定大小的核心线程数(2),最大线程数(4),以及指定存活时间为零秒的线程池,
// 使用LinkedBlockingQueue作为阻塞队列,并设置初始容量为5.
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
4,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
// 提交多个任务...
for (int i = 0; i < 10; ++i){
final int taskNumber = i;
executor.execute(() -> System.out.println("Executing Task " + taskNumber));
}
// 关闭线程池
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
}
```
上述例子中选择了`CallerRunsPolicy`作为拒绝策略,这意味着如果遇到超出承载能力的情况,那么提交任务的地方(即main函数内部)将会亲自承担起执行这项工作的责任。
阅读全文
相关推荐

















