一、首先我们要知道什么是拒绝策略:
线程池中,有三个重要的参数,决定影响了拒绝策略:corePoolSize - 核心线程数,也即最小的线程数。workQueue - 阻塞队列 。 maximumPoolSize - 最大线程数。
当提交任务数大于 corePoolSize 的时候,会优先将任务放到 workQueue 阻塞队列中。当阻塞队列饱和后,会扩充线程池中线程数,直到达到 maximumPoolSize 最大线程数配置。此时,再多余的任务,则会触发线程池的拒绝策略了。总结起来,也就是一句话,当提交的任务数大于(workQueue.size() + maximumPoolSize ),就会触发线程池的拒绝策略。
二、然后我们要了解线程池的拒绝策略都有哪四种:
策略 | 处理方式 |
AbortPolicy | 直接抛出异常 |
DiscardPolicy | 丢弃当前被拒绝的任务(不抛出异常) |
DiscardOldestPolicy | 将工作队列中最早的任务丢弃,去执行新的任务 |
CallerRunsPolicy | 交给调用线程池的线程处理 |
二、下面用代码给大家进一步演示一下
1. AbortPolicy
- public static void main(String[] args) throws Exception{
- int corePoolSize = 5;
- int maximumPoolSize = 10;
- long keepAliveTime = 5;
- BlockingQueue
workQueue = new LinkedBlockingQueue(10); - RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
- ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
- for(int i=0; i<100; i++) {
- try {
- executor.execute(new Thread(() -> log.info(Thread.currentThread().getName() + " is running")));
- } catch (Exception e) {
- log.error(e.getMessage(),e);
- }
- }
- executor.shutdown();
- }
2. DiscardPolicy
主体相同,更换拒绝策略
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
3. DiscardOldestPolicy
主体相同,更换拒绝策略
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
4. CallerRunsPolicy
主体相同,更换拒绝策略
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
以上是线程池的四种拒绝策略.