当前位置: 首页 > news >正文

【JUC】线程池有哪些拒绝策略?该如何选择使用?

线程池的拒绝策略有哪些?

线程池的拒绝策略(Rejection Policy)是指当线程池无法接受新提交的任务时采取的应对措施。这通常发生在以下情况:

  1. 线程池已关闭(shutdown)。
  2. 线程池的工作线程已满(达到 maximumPoolSize)且等待队列已满(达到 workQueue 的容量)。
    Java 的 ThreadPoolExecutor 类提供了四种内置的拒绝策略,它们都实现了 RejectedExecutionHandler 接口。

(1) AbortPolicy(中止策略 - 默认策略)

  • 行为:直接抛出 RejectedExecutionException 异常。
  • 优点:策略明确,抛出异常便于开发者感知问题,及时做后续处理(如回滚、重试等)。
  • 缺点:会中断当前提交任务的流程。
  • 使用场景:关键业务,需要确保提交的每一个任务都被执行,并且能够及时感知到系统过载的情况。例如,交易、订单等系统。

(2) CallerRunsPolicy(调用者运行策略)

  • 行为:不抛弃任务,也不抛出异常。而是将某些被拒绝的任务回退给调用者线程(即提交该任务的线程)来执行
  • 优点:
    • 不会丢弃任务,保证了所有任务都能得到执行。
    • 提交任务的线程被占用来执行任务,在此期间它无法继续提交新任务,这相当于给了线程池一个“减速”的机会,有助于缓和提交任务的速度。
  • 缺点:可能会影响调用者线程(如 Tomcat 的 HTTP 处理线程)的响应速度。
  • 使用场景:需要保证所有任务都必须被执行,且可以接受短期同步执行的场景。常用于不允许任务丢失,但对实时性要求不非常极端的应用。

(3) DiscardPolicy(丢弃策略)

  • 行为:静默地直接丢弃无法处理的新任务,不抛出任何异常,就像这个任务从来没被提交过一样。
  • 优点:对调用者无感知,不会影响当前业务流程。
  • 缺点:任务被无声无息地丢弃,可能导致数据不一致或业务逻辑缺失,问题难以排查。
  • 使用场景:非关键业务,允许丢失一些任务。例如,日志收集、无关紧要的统计信息上报等。

(4) DiscardOldestPolicy(丢弃最老策略)

  • 行为:丢弃等待队列中最老(即下一个即将被线程执行)的任务,然后尝试重新提交当前这个被拒绝的新任务。
  • 优点:给了新任务一次机会,避免了最新的任务被丢弃。
  • 缺点:
    • 会丢弃一个正在排队的老任务。
    • 任务丢弃是静默的,同样存在数据不一致的风险。
    • 如果任务之间有依赖顺序,可能会导致问题。
  • 使用场景:新任务比老任务优先级更高的场景。例如,消息队列中,新的消息可能比积压的旧消息更有价值。

(5) 自定义拒绝策略

如果以上四种内置策略都不满足需求,你可以通过实现 RejectedExecutionHandler 接口来自定义拒绝策略

public class MyRejectionPolicy implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {// 自定义处理逻辑,例如:// 1. 将任务持久化到磁盘,待系统恢复后重新加载// 2. 记录日志并发送告警// 3. 尝试等待一段时间后重新放入队列System.out.println("Task " + r.toString() + " was rejected. Doing something special...");// 尝试重新提交一次(注意:这可能不是个好主意,容易造成循环)// if (!executor.isShutdown()) {//     executor.execute(r);// }}
}// 使用自定义策略ThreadPoolExecutor customExecutor = new ThreadPoolExecutor(..., new MyRejectionPolicy());

几种拒绝策略该如何选择?

拒绝策略的总结:

策略名称行为优点缺点适用场景
AbortPolicy抛出异常明确感知问题中断流程关键业务(默认)
CallerRunsPolicy回调给调用者不丢弃任务,减缓提交速度可能阻塞调用者不允许丢失,可同步执行
DiscardPolicy静默丢弃新任务不影响调用流程任务丢失无感知非关键业务(如日志)
DiscardOldestPolicy丢弃队列头任务给新任务一次机会丢弃老任务,有顺序风险新任务优先级更高
  • 如果不确定,使用默认的 AbortPolicy 是最安全的选择,因为它能让你第一时间发现问题。
  • 如果任务绝对不能丢,但又不想抛异常中断流程,可以考虑 CallerRunsPolicy。
  • 如果任务可以丢弃,根据重要性选择是丢弃新的(DiscardPolicy)还是丢弃老的(DiscardOldestPolicy)。
  • 通常,DiscardPolicy 和 DiscardOldestPolicy 用于那些即使丢失部分任务也完全不影响主流程的场景。

最好的策略是合理配置线程池参数(如核心线程数、最大线程数、队列类型和容量)来尽量避免拒绝的发生,拒绝策略只是一种最后的保护手段。

http://www.dtcms.com/a/474305.html

相关文章:

  • 4 随机数 从一个随机数到另外一个随机数、等概率随机
  • 机器学习17:如何有效使用自监督式学习
  • 生成对抗网络(GAN)及其变种:CycleGAN和StarGAN
  • dede网站地图html文件公司部门撤销要求转岗不同意怎么办
  • 国外购买空间的网站有哪些最优惠的网站优化
  • Linux安装JDK1.8 tomcat MariaDB(MySQL删减版)
  • 【C++】C++中的异常处理try-catch
  • 珠海专业做网站的公司交友软件
  • rclone:安装与配置
  • 第128题 最长连续序列
  • 深度学习》【项目】自然语言处理——情感分析 <上>
  • 在哪里申请网站域名免费制作表白网页
  • 外设模块学习(6)——DHT11温湿度传感器(STM32)
  • 创造网站软件icp备案查询
  • 计算机视觉——从YOLO系列演进到YOLOv12架构创新、注意力机制优化、推理实践与性能基准
  • 广州网站建设公司广州企业网站建设公司公司网站建设网站建设合同需要印花税
  • 门户网站开发需求律师网络推广
  • FSR《软件开发可行性分析报告》全面概述
  • 鸿蒙开发实战:从零构建可扩展的数据迁移机制,让数据库升级不再崩
  • java接收小程序发送的protobuf消息
  • 沧州市高速公路建设管理局网站龙岩天宫山有几个台阶
  • 闽侯做网站做国际物流需要哪些网站
  • 【Swift】LeetCode 49. 字母异位词分组
  • 对网站建设建议外加工活怎么直接找厂家接单
  • (17)100天python从入门到拿捏《正则表达式》
  • 【C++】深入理解list底层:list的模拟实现
  • 用Spring Cloud打造健壮服务:熔断与降级如何护航核心业务
  • 网站平台怎么推广企业的做网站
  • 机器学习-推荐系统(上)
  • 网站建设费用的财务核算三丰云服务器