美文网首页
Java线程池-拒绝策略

Java线程池-拒绝策略

作者: Toyouy | 来源:发表于2020-08-10 15:38 被阅读0次

Java 在 ThreadPoolExecutor 类中为我们提供了 4 种默认的拒绝策略来应对不同的场景,都实现了 RejectedExecutionHandler 接口。

拒绝策略

  • ThreadPoolExecutor.AbortPolicy()
    • 这种拒绝策略在拒绝任务时,会直接抛出一个类型为 RejectedExecutionException 的RuntimeException,让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。
  • ThreadPoolExecutor.DiscardPolicy()
    • 这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。
  • ThreadPoolExecutor.DiscardOldestPolicy()
    • 如果线程池没被关闭且没有能力执行,则会丢弃任务队列中的头结点,通常是存活时间最长的任务,这种策略与第二种不同之处在于它丢弃的不是最新提交的,而是队列中存活时间最长的,这样就可以腾出空间给新提交的任务,但同理它也存在一定的数据丢失风险。
  • ThreadPoolExecutor.CallerRunsPolicy()
    • 相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。这样做主要有两点好处。
      • 第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。
      • 第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。

拒绝时机

首先,新建线程池时可以指定它的任务拒绝策略,例如:

newThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
   new ThreadPoolExecutor.DiscardOldestPolicy());

拒绝任务的时机是什么呢? 线程池会在以下两种情况下会拒绝新提交的任务。

  • 第一种情况是当我们调用 shutdown 等方法关闭线程池后,即便此时可能线程池内部依然有没执行完的任务正在执行,但是由于线程池已经关闭,此时如果再向线程池内提交任务,就会遭到拒绝。
    第二种情况是线程池没有能力继续处理新提交的任务,也就是工作已经非常饱和的时候。
  • 第二种情况,也就是由于工作饱和导致的拒绝。比如新建一个线程池,使用容量上限为 10 的 ArrayBlockingQueue 作为任务队列,并且指定线程池的核心线程数为 5,最大线程数为 10,假设此时有 20 个耗时任务被提交,在这种情况下,线程池会首先创建核心数量的线程,也就是5个线程来执行任务,然后往队列里去放任务,队列的 10 个容量被放满了之后,会继续创建新线程,直到达到最大线程数 10。此时线程池中一共有 20 个任务,其中 10 个任务正在被 10 个线程执行,还有 10 个任务在任务队列中等待,而且由于线程池的最大线程数量就是 10,所以已经不能再增加更多的线程来帮忙处理任务了,这就意味着此时线程池工作饱和,这个时候再提交新任务时就会被拒绝。

相关文章

  • Java线程池拒绝策略

    【Java线程池拒绝任务策略】创建线程池可以指定拒绝策略如下: 一 拒绝时机1) 调用线程池的shutdown函数...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • ThreadPoolExecutor的RejectedExecu

    java 线程池ThreadPoolExecutor的拒绝策略有: CallerRunsPolicy : 当线程池...

  • 线程池

    Java中的多线程了解么,线程池的增长策略和拒绝策略了解么java.util.concurrent.ThreadP...

  • ThreadPoolExecutor

    线程池 拒绝策略 线程池的拒绝策略,即任务被添加到线程池中被拒绝而采取的处理措施。任务被拒绝的原因可能有: 线程池...

  • Java线程池-拒绝策略

    Java 在 ThreadPoolExecutor 类中为我们提供了 4 种默认的拒绝策略来应对不同的场景,都实现...

  • Java基础 -- 线程拒绝策略

    什么是线程拒绝策略 当线程池达到饱和状态时,新提交的任务需要一种处理方法,这也就出现了拒绝策略。Java中提供了四...

  • 线程池

    线程池执行过程 线程池生命周期 线程池分类 阻塞队列 拒绝策略 - ThreadPoolExecutor.Abor...

  • 线程池概述

    为什么要使用线程池? 线程池核心参数 线程池的几种拒绝策略 execute()和submit()的区别 线程池工作...

  • 信号量用法:锁

    用于dubbo线程池满的拒绝策略

网友评论

      本文标题:Java线程池-拒绝策略

      本文链接:https://www.haomeiwen.com/subject/hrjjdktx.html