线程池策略

2021-04-08  本文已影响0人  java_飞

线程池策略设置对业务的影响

1.AbortPolicy中止策略

2.DiscardPolicy丢弃策略

3.DiscardOldestPolicy弃老策略

4.CallerRunsPolicy调用者运行策略


AbortPolicy中止策略:
简介:线程池默认的拒绝策略,在任务不能再提交的时候,抛出异常,及时反馈程序运行状态

功能:当触发拒绝策略时,直接抛出拒绝执行的异常,中止策略的意思也就是打断当前执行流程.

使用场景:这个就没有特殊的场景了,但是有一点要正确处理抛出的异常。
ThreadPoolExecutor中默认的策略就是AbortPolicy,ExecutorService接口
系列ThreadPoolExecutor因为都没有显示的设置拒绝策略,所以默认的都
是这个。但是请注意,ExecutorService中的线程池实例队列都是无界的,
也就是说把内存撑爆了都不会触发拒绝策略。当自己自定义线程池实例时,
使用这个策略一定要处理好触发策略时抛的异常,因为他会打断当前的执行流程。

DiscardPolicy丢弃策略:
简介:ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。

功能:直接静悄悄的丢弃这个任务,不触发任何动作。

使用场景:如果你提交的任务无关紧要,你就可以使用它 。因为它就是个空实现,会悄无声息的吞噬你的的任务。所以这个策略基本上不用了。

例如:浏览数统计,点赞数统计等

DiscardOldestPolicy弃老策略:
简介:此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量。

功能:如果线程池未关闭,就弹出队列头部的元素,然后尝试执行

使用场景:这个策略还是会丢弃任务,丢弃时也是毫无声息,但是特点是丢弃的是老的未执行的任务,而且是待执行优先级较高的任务。基于这个特性,想到的场景就是,发布消息和修改消息,当消息发布出去后,还未执行,此时更新的消息又来了,这个时候未执行的消息的版本比现在提交的消息版本要低就可以被丢弃了。因为队列中还有可能存在消息版本更低的消息会排队执行,所以在真正处理消息的时候一定要做好消息的版本比较

CallerRunsPolicy调用者运行策略:
功能:当触发拒绝策略时,只要线程池没有关闭,就由提交任务的当前线程处理

使用场景:一般在不允许失败的、对性能要求不高、并发量较小的场景下使用,
因为线程池一般情况下不会关闭,也就是提交的任务一定会被运行,但是由于
是调用者线程自己执行的,当多次提交任务时,就会阻塞后续任务执行,性能
和效率自然就慢了。

例如:kafka消费者线程,必须消费完了以后再去拉去消息

以上引自:https://www.cnblogs.com/waitmoon/p/13442193.html

实战过程:
在压力测试过程中发现使用CallerRunsPolicy策略的线程池严重影响了主业务,因为当线程线程数以及队列数满了以后就会默认使用tomcat主线程去跑,导致整个服务没有线程可用,从而导致其他业务受到影响;

优化方案:使用消息中间件来代替线程池走异步逻辑;

上一篇下一篇

猜你喜欢

热点阅读