线程池拒绝策略 开发中常用什么策略_线程池有哪 4 种拒绝策略?

线程池拒绝策略 开发中常用什么策略_线程池有哪 4 种拒绝策略?_第1张图片
本文我们一起学习线程池有哪 4 种默认的拒绝策略。

线程池的拒绝策略

若线程池中的核心线程数被用完且阻塞队列已排满,则此时线程池的资源已耗尽,线程池将没有足够的线程资源执行新的任务。为了保证操作系统的安全,线程池将通过拒绝策略处理新添加的线程任务。

1. AbortPolicy

第一种拒绝策略是 AbortPolicy,这种拒绝策略在拒绝任务时,会直接抛出一个类型为 RejectedExecutionException的RuntimeException,让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。

2.DiscardPolicy

第2种拒绝策略是 DiscardPolicy,这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。

3.DiscardOldestPolicy

第3种拒绝策略是 DiscardOldestPolicy,如果线程池没被关闭且没有能力执行,则会丢弃任务队列中的头结点,通常是存活时间最长的任务,这种策略与第二种不同之处在于它丢弃的不是最新提交的,而是队列中存活时间最长的,这样就可以腾出空间给新提交的任务,但同理它也存在一定的数据丢失风险。

4.CallerRunsPolicy

第4种拒绝策略是 CallerRunsPolicy,相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。这样做主要有两点好处。

  1. 第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。
  2. 第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。

总结

本文中我们学习线程池中的4 种默认的拒绝策略。线程池会在以下两种情况下会拒绝新提交的任务。

  • 第一种情况是当我们调用 shutdown 等方法关闭线程池后,即便此时可能线程池内部依然有没执行完的任务正在执行,但是由于线程池已经关闭,此时如果再向线程池内提交任务,就会遭到拒绝。
  • 第二种情况是线程池没有能力继续处理新提交的任务,也就是工作已经非常饱和的时候。

推荐阅读

  • 建议收藏|全网最全的操作系统面试题
  • 建议收藏 | Linux 命令汇总
  • Java面试中碰到这样的MyBatis面试题,你会回答吗?
  • Java 100+ 经典面试题大全&答案,剑指名企Offer !
  • 实际开发中我们如何才能正确停止线程?
  • 揭秘在使用多线程时为什么会带来性能问题?
  • 关于wait/notify/notifyAll 方法的使用注意事项
  • 都是线程安全,ConcurrentHashMap和Hashtable有什么区别?
  • 实际工作中可能会遇到三类线程安全问题

你可能感兴趣的:(线程池拒绝策略,开发中常用什么策略,线程池的拒绝策略)