ExecutorService 之所以会拒绝任务,本质上是因为:线程池已经没有能力接收新提交的任务了。
在 Java 中,这种行为由 拒绝策略(RejectedExecutionHandler) 来控制。
下面从「为什么会拒绝」和「什么时候会拒绝」两个角度说明。
ThreadPoolExecutor 在以下 两种情况同时满足 时会拒绝任务:
线程池已经 SHUTDOWN / STOP
shutdown() 或 shutdownNow()线程池“满了”
maximumPoolSize此时再提交任务,就会触发 拒绝策略。
线程池运行逻辑简化如下:
提交任务
↓
1. 小于 corePoolSize → 创建核心线程
2. 核心线程满 → 放入队列
3. 队列满 → 创建非核心线程(直到 maxPoolSize)
4. 线程数 = maxPoolSize 且队列满 → 拒绝任务
所以拒绝发生在:
线程数已达最大值 + 队列已满 + 还有新任务
new ThreadPoolExecutor(
2, 4,
0L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10) // 只能存 10 个
);
SynchronousQueuenew ThreadPoolExecutor(
2, 4,
0L, TimeUnit.SECONDS,
new SynchronousQueue<>()
);
sleep导致线程长期不释放。
executor.shutdown();
executor.submit(task); // 拒绝
| 策略 | 行为 |
|---|---|
AbortPolicy(默认) |
抛 RejectedExecutionException |
CallerRunsPolicy |
提交任务的线程自己执行 |
DiscardPolicy |
直接丢弃 |
DiscardOldestPolicy |
丢弃队列中最老任务 |
new ThreadPoolExecutor(
10, 50,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000),
new ThreadPoolExecutor.CallerRunsPolicy()
);
executor.getActiveCount();
executor.getQueue().size();
ExecutorService 拒绝任务,是因为线程池已经“既没线程,也没地方排队”,且仍然收到新任务。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。