之前在文章深入线程池ThreadPoolExecutor中聊到了线程池的核心参数,运行原理等,今天我们说下饱和策略CallerRunsPolicy。

 

一、CallerRunsPolicy策略定义

     "该策略既不会抛弃任务,也不会抛出异常,而是将任务回推到调用者。"顾名思义,在饱和的情况下,调用者会执行该任务。

 

二、一次异常回顾

    分享一次使用CallersRunPolicy饱和策略遇到的坑。

    我们在业务主流程中通过线程池去处理任务,同步非阻塞的方式获取数据后继续执行后面的流程,代码模型大致如下:

public void process() {

    ThreadPoolExecutor pool = new ThreadPoolExecutor(xx,xx, new CallerRunsPolicy());

    Future future = pool.submit(new Callable(
        //request http without timeout
    ));

    Result result = future.get(200);
}

流程图:

问题在于:

当流量比较大的时候,由于任务没有设置超时时间,处理线程会一直hang住,导致线程池被打满的时候触发饱和策略CallerRunsPolicy,由主线程去处理任务,而任务又是阻塞的,主线程hang主,从而导致主流程超时,发生故障。所以在使用饱和策略的时候需要考虑一下场景,看看是否合适,以免踩坑。

 

解决方案:

   将饱和策略调整为默认的Abort以及discard都可以,类似于一种降级手段,不要影响主流程即可。

 

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐