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)也不会超时结束。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容