CompletableFuture避坑3——线程池的DiscardPolicy()导致整个程序卡死

CompletableFuture避坑1——需要自定义线程池
CompletableFuture避坑2——allOf()超时时间不合理的后果
CompletableFuture避坑3——线程池的DiscardPolicy()导致整个程序卡死


CompletableFuture处理多线程任务时一般建议自定义线程池,线程池有个容量满了的处理策略:

  • ThreadPoolExecutor.DiscardPolicy()
  • ThreadPoolExecutor.DiscardOldestPolicy()
  • ThreadPoolExecutor.AbortPolicy()
  • ThreadPoolExecutor.CallerRunsPolicy()
    分别对应:
  • 丢弃新提交的任务
  • 丢弃等待中的最早的任务
  • 抛异常,RejectedExecutionException
  • 线程池不接任务,由提交任务的线程自己执行
    也可以自己实现RejectedExecutionHandler接口:
new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        log.error("xxx");
        throw new RuntimeException();
    }
});

可以抛出异常,可以忽略,也可以做其他处理。
用子线程执行有兜底策略的任务(例如执行失败了使用默认数据等)时,如果线程池满了,我们经常会设置为打日志(不报警也不抛异常),统计失败数量,失败数量在一定范围内则忽略影响。这在以前是没问题的。
开始使用jdk8的新API CompletableFuture 之后,CompletableFuture.allOf()方法或者get()方法等待所有CompletableFuture执行完时,如果采用丢弃策略(包括自定义的不抛异常),则allOf()方法和get()方法会无限期的等待下去,即使allof()设置了orTimeout(2000, TimeUnit.MILLISECONDS)、get()使用get(2000, TimeUnit.MILLISECONDS)也不会超时结束。

你可能感兴趣的:(CompletableFuture避坑3——线程池的DiscardPolicy()导致整个程序卡死)