一.什么是线程池的拒绝策略?
我们知道在线程池中,有三个重要的参数,决定影响了拒绝策略:
1.corePoolSize - 核心线程数,也即最小的线程数。
2.workQueue - 阻塞队列 。
3.maximumPoolSize - 最大线程数
当提交任务数大于 corePoolSize 的时候,会优先将任务放到 workQueue 阻塞队列中。当阻塞队列饱和后,会扩充线程池中线程数,直到达到 maximumPoolSize 最大线程数配置。此时,再多余的任务,则会触发线程池的拒绝策略了。总结起来,也就是一句话,当提交的任务数大于(workQueue.size() + maximumPoolSize ),就会触发线程池的拒绝策略。
二.线程池的拒绝策略有哪些?
1、AbortPolicy
当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常。(该策略下,直接丢弃任务,并抛出RejectedExecutionException异常)
2、DiscardPolicy
当任务添加到线程池中被拒绝时,默认情况下它将丢弃被拒绝的任务。(即该策略下,直接丢弃任务,什么都不做)
3、DiscardOldestPolicy
当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。(该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列)
4、CallerRunsPolicy
不进入线程池执行,在这种方式(CallerRunsPolicy)中,任务将由调用者线程去执行。(用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务。)
三.小结一下
四种拒绝策略是相互独立无关的,当我们去选择何种策略去执行的时候,还得结合具体的业务场景。实际工作中,一般直接使用 ExecutorService 的时候,都是使用的默认的 defaultHandler ,也就是 AbortPolicy 策略。