线程池的拒绝策略

一、线程池

线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象。

二、线程池的优势

  • 降低资源消耗。

    • 通过重复利用已创建的线程降低线程创建和销毁造成的消耗

  • 提高响应速度

    •  当断服务到达时,任务不需要等到线程创建就能立即执行。
  • 提高线程的可管理性。

    • 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配,调优和监控。

三、线程池的使用

参数最多的构造方法
                  public ThreadPoolExecutor(
                          int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler);


参数解释:
 *                 1.corePoolSize:线程池核心大小
 *                 2.maximumPoolSize:最大线程池大小
 *                 3.keepAliveTime 和 unit 合在一起用于指定线程池中空闲线程的最大存活时间
 *                 4.workQueue:工作队列
 *                 5.threadFactory:用于创建工作者线程的线程工厂
 *                 6.handler:线程池饱和时,封装被拒绝任务的处理策略

四、线程池的工作流程

  1. 创建任务提交给线程池。
  2. 在线程池中创建核心线程去执行任务,如果此时核心线程池已满,则将任务放入队列中,等待别的任务执行完毕后再去执行。
  3. 如果队列也存满任务,则去判断线程池是否已达到最大线程。
  4. 如果没有达到最大线程数,则去开启一个非核心线程去执行任务。
  5. 如果已经已经达到再次大线程数,则会根据拒绝策略去拒绝任务的执行。

五、线程的拒绝策略

        关于RejectedExecutionHandler操作说明:

  1. 当客户端提交的任务被拒绝时,线程池所关联的RejectedExecutionHandler的rejectedExecution方法会被线程池调用。
  2. ThreadPoolExecutor自身提供了几个现成的RejectedExecutionHandler接口的实现类。其中ThreadPoolExecutor.AbortPolicy是ThreadPoolExecutor使用的默认RejectedExecutionHandler。
  3. 如果默认的RejectedExecutionHandler(它会直接抛出异常)无法满足要求,那么我们可以优先考虑ThreadPoolExecutor自身提供的其他RejectedExecutionHandler,其次才去考虑使用自身实现的RejectedExecutionHandler接口。

拒绝策略详解

AbortPolicy

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

DiscardPolicy

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

DiscardOldestPolicy

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

CallerRunsPolicy

  • 第四种拒绝策略是 CallerRunsPolicy,相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。这样做主要有两点好处。
    • 第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。
    • 第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。

六、总结

        本文简述了线程池的工作流程以及四种拒绝服务策略,这四种拒绝策略可根据实际开发的需要去使用。

        喜欢的小伙伴点个小红心吧~

  • 17
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值