拒绝策略
AbortPolicy:默认的拒绝策略,直接抛出RejectedExecutionException异常。
CallerRunsPolicy:将任务退回给调用者执行。
场景
等线程池里的任务执行完通过future.get的方式获取线程池里的线程执行结果,然后合并到主流程的结果里返回给前端。
代码
// 如果线程池已满,新的请求会直接执行拒绝策略
Future<String> future = executor.submit(() -> {
// 业务逻辑,比如调用第三方接口等耗时操作放在线程池里执行
return result;
});
// 主流程调用逻辑
if(future != null) // 如果拒绝策略设置不合理还是会走到下面代码
future.get(超时时间); // 调用方阻塞等待结果返回,直到超时
问题
当线程池达到最大负荷时执行的拒绝策略是让主流程去执行提交到线程池里的任务,这样除了进一步加剧整个接口的耗时外,还会导致主流程被hang死,最关键的是无法确定是在哪一步执行提交到线程池的任务。
DiscardPolicy:直接丢弃任务,不做任何处理。
DiscardOldestPolicy:丢弃最老的一个任务,然后尝试再次提交当前任务。
线程池的执行流程
1.线程池中线程数小于corePoolSize时,新任务将创建一个新线程执行任务,不论此时线程池中存在空闲线程;
2.线程池中线程数达到corePoolSize时,新任务将被放入workQueue中,等待线程池中任务调度执行;
3.当workQueue已满,且maximumPoolSize>corePoolSize时,新任务会创建新线程执行任务;
4.当workQueue已满,且提交任务数超过maximumPoolSize,任务由RejectedExecutionHandler处理;
5.当线程池中线程数超过corePoolSize,且超过这部分的空闲时间达到keepAliveTime时,回收该线程;
6.如果设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize范围内的线程空闲时间达到keepAliveTime也将回收;
核心参数
基于上述描述需要参数
corePoolSize 核心线程
workQueue 任务队列,被提交但尚未被执行的任务
maximumPoolSize 线程池能够容纳同时执行的最大线程数,此值大于等于1。
keepAliveTime:多余的空闲线程存活时间,当空间时间达到keepAliveTime值时,多余的线程会被销毁直到只剩下corePoolSize个线程为止。
unit:keepAliveTime的单位。
handler:拒绝策略。
threadFactory:表示生成线程池中工作线程的线程工厂,用户创建新线程,一般用默认即可