动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

浅谈线程池的4种拒绝策略

05-24 11:35 725浏览
举报 T字号
  • 大字
  • 中字
  • 小字

我们之前讲过的任务拒绝模块是线程池的保护部分,线程池有一个最大的容量,当线程池的任务缓存队列已满,并且线程池中的线程数目达到maximumPoolSize时,就需要拒绝掉该任务,采取任务拒绝策略,保护线程池。拒绝策略其实是一个接口,用户可以通过实现这个接口去定制拒绝策略,也可以选择JDK提供的四种已有拒绝策略。下面我们就来讲一讲JDK内置的4种拒绝策略。

1.CallerRunsPolicy(调用者运行策略)

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

2.AbortPolicy(中止策略)

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

3.DiscardPolicy(丢弃策略)

如果你提交的任务无关紧要,你就可以使用它 。因为它就是个空实现,会悄无声息的吞噬你的的任务。它就是直接静悄悄的丢弃这个任务,不触发任何动作。所以这个策略基本上不用了。

4.DiscardOldestPolicy(弃老策略)

这个策略依然会丢弃任务,丢弃时也是无声无息,但丢弃的是老的未执行的任务,而且是待执行优先级较高的任务。基于这个特性,我能想到的场景就是,发布消息,和修改消息,当消息发布出去后,还未执行,此时更新的消息又来了,这时未执行的消息的版本比现在低就可以被丢弃了。因为队列中还可能存在消息版本更低的消息会排队执行,所以在真正处理消息的时候一定要做好消息的版本比较。此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量。

正如我们开头所说的那样,拒绝策略其实是一个接口,那么如何实现这个接口来实现拒绝策略呢?我们可以到动力节点在线的免费视频课程中寻找你需要的答案。

0人推荐
共同学习,写下你的评论
0条评论
代码小兵652
程序员代码小兵652

113篇文章贡献392215字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

提枪策马乘胜追击04-21 20:01

Spring常见面试题

代码小兵92504-17 16:07

Java零基础实战项目——五子棋

代码小兵98804-25 13:57

Java string类详解

杨晶珍05-11 14:54

6道经典算法面试题

杨晶珍05-12 16:39

发评论

举报

0/150

取消