news 2026/7/5 6:42:19

线程池四种拒绝策略(ThreadPoolExecutor 内置)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
线程池四种拒绝策略(ThreadPoolExecutor 内置)

线程池四种拒绝策略(ThreadPoolExecutor 内置)

当满足线程池饱和条件时触发拒绝:

  1. 核心线程全部繁忙
  2. 阻塞队列已满
  3. 最大线程数已达到上限
    此时新提交任务会走拒绝策略,JDK 内置 4 种实现。

前置基础构造示意

// 核心线程2,最大5,队列容量3,空闲线程存活0sThreadPoolExecutorexecutor=newThreadPoolExecutor(2,5,0L,TimeUnit.MILLISECONDS,newArrayBlockingQueue<>(3));// 设置拒绝策略executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());

饱和临界点:同时提交超过maxPoolSize + queueSize = 5+3=8个任务,第9个开始触发拒绝策略。


1. AbortPolicy(默认策略:直接抛出异常)

代码

executor.setRejectedExecutionHandler(newThreadPoolExecutor.AbortPolicy());

行为

直接抛出RejectedExecutionException,中断当前任务提交,不执行任务。

示例

for(inti=0;i<10;i++){executor.submit(()->{try{Thread.sleep(10000);}catch(InterruptedExceptione){e.printStackTrace();}});}

提交第9个任务直接抛异常,程序不捕获会中断业务流程。

使用场景

  • 任务不允许丢失,且调用方必须感知失败、主动降级重试;
  • 同步阻塞业务、支付、核心数据处理,不允许静默丢失任务;
  • 小型同步接口,任务量可控,异常统一捕获做告警/重试。

2. DiscardPolicy(丢弃当前新任务,无任何提示)

代码

executor.setRejectedExecutionHandler(newThreadPoolExecutor.DiscardPolicy());

行为

默默丢掉新来的任务,不抛异常、无日志、无告警,调用方无感知。

风险

任务永久丢失,业务数据缺失很难排查。

使用场景

  • 非核心、可丢弃的统计上报、埋点日志、实时监控采集;
  • 允许数据丢失、对一致性无要求的边缘辅助任务。

3. DiscardOldestPolicy(丢弃队列最老未执行任务,执行新任务)

代码

executor.setRejectedExecutionHandler(newThreadPoolExecutor.DiscardOldestPolicy());

行为

取出阻塞队列头部排队最久的任务丢弃,再尝试提交当前新任务。

使用场景

  • 实时数据、最新状态覆盖旧数据:如设备实时状态上报、行情推送;
  • 旧任务无保留价值,最新数据才有效,不需要历史排队任务。

不适用场景

订单、入库、消息消费等顺序/历史任务不能丢的业务。


4. CallerRunsPolicy(调用者线程执行,你提问中的策略)

代码(你给出的)

executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());

行为

不丢任务、不抛异常,把当前任务交给提交任务的主线程同步执行
举例子:主线程调用executor.submit(),池子满了,任务直接在主线程跑,阻塞主线程直到任务完成。

效果

  1. 不会丢失任何任务;
  2. 提交线程被阻塞,天然限流;
  3. 减缓任务提交速度,给线程池留出时间处理堆积。

示例演示

ThreadPoolExecutorexecutor=newThreadPoolExecutor(2,5,0L,TimeUnit.MILLISECONDS,newArrayBlockingQueue<>(3),newThreadPoolExecutor.CallerRunsPolicy());// 模拟10个长耗时任务for(inti=0;i<10;i++){inttaskId=i;System.out.println("提交任务:"+taskId+" 提交线程:"+Thread.currentThread().getName());executor.submit(()->{System.out.println("执行任务:"+taskId+" 执行线程:"+Thread.currentThread().getName());try{Thread.sleep(3000);}catch(InterruptedExceptione){}});}

输出现象:前8个由池内线程执行,第9、10个任务打印执行线程为main,主线程同步执行。

使用场景

  1. 流量削峰、不允许丢任务:文件同步、数据库批量入库、定时采集任务(你项目采集接口非常适配);
  2. 无独立重试机制、任务丢失会造成业务数据缺失;
  3. 接口流量突增时,自动降级为调用线程执行,起到限流保护线程池;
  4. Spring 内置定时池、普通业务异步线程池常用该策略。

缺点

高并发下主线程阻塞,接口响应时间变长,吞吐量下降。


四种策略对比表

策略处理逻辑是否丢任务是否抛异常典型适用场景
AbortPolicy抛异常拒绝丢当前任务核心交易、需感知失败的同步业务
DiscardPolicy静默丢弃新任务丢当前任务非核心埋点、监控日志
DiscardOldestPolicy丢弃队列最老任务丢旧任务实时状态、行情推送
CallerRunsPolicy调用线程同步执行不丢失数据采集、入库、定时任务、流量削峰

生产使用建议(结合你项目采集定时任务)

你的业务是http采集定时任务,推荐CallerRunsPolicy

  1. 采集数据不能丢,丢弃会造成数据断层;
  2. 池子打满时主线程同步执行,自动限流,避免无限创建任务OOM;
  3. 无需额外编写重试、丢失补偿逻辑。

拓展:自定义拒绝策略(生产常用兜底)

内置策略无法满足告警需求时自定义,打印日志+推送告警:

publicclassCustomRejectHandlerimplementsRejectedExecutionHandler{@OverridepublicvoidrejectedExecution(Runnabler,ThreadPoolExecutorexecutor){log.error("线程池饱和,任务被拒绝,核心:{},最大:{},队列容量:{}",executor.getCorePoolSize(),executor.getMaximumPoolSize(),executor.getQueue().size());// 推送钉钉/短信告警// 可选:本地持久化任务,后续补偿thrownewRuntimeException("任务提交失败,线程池已满");}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 6:37:50

浏览器一键解锁网盘全速下载:八大平台直链获取终极方案

浏览器一键解锁网盘全速下载&#xff1a;八大平台直链获取终极方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…

作者头像 李华
网站建设 2026/7/5 6:37:09

Python路径优先级问题解决方案核心原因

核心原因&#xff1a;PATH 环境变量的「从上到下检索规则」where python 的输出顺序&#xff0c;就是系统在 PATH 中查找 python.exe 的优先级顺序—— 系统会从第一条路径开始找&#xff0c;找到第一个匹配的 python.exe 就会停止检索&#xff0c;这个版本就会成为你输入 pyth…

作者头像 李华
网站建设 2026/7/5 6:36:52

Linux/macOS使用Dislocker解锁BitLocker加密硬盘完整指南

1. 项目概述&#xff1a;当BitLocker遇上非Windows世界 如果你手头有一块从Windows电脑上拆下来的硬盘&#xff0c;或者一个移动硬盘&#xff0c;上面用BitLocker加密了分区&#xff0c;现在想在Linux或macOS上读取里面的数据&#xff0c;是不是感觉有点无从下手&#xff1f;这…

作者头像 李华
网站建设 2026/7/5 6:36:42

LinkSwift:九大网盘直链下载的完整解决方案

LinkSwift&#xff1a;九大网盘直链下载的完整解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷…

作者头像 李华
网站建设 2026/7/5 6:32:40

MAX9744与PIC24FV32KA304构建高效D类音频放大系统

1. MAX9744与PIC24FV32KA304的强强联合在音频功率放大领域&#xff0c;D类放大器因其高效率特性已成为现代音频系统的首选方案。MAX9744作为Analog Devices推出的20W立体声D类音频功率放大器&#xff0c;与Microchip的PIC24FV32KA304单片机组合&#xff0c;能够构建出高性能的程…

作者头像 李华
网站建设 2026/7/5 6:31:54

stortrace块设备追踪详解:从bio提交到NVMe执行的完整链路分析

stortrace块设备追踪详解&#xff1a;从bio提交到NVMe执行的完整链路分析 【免费下载链接】stortrace High-performance IO tracing and analysis tool based ebpf mechanism. 项目地址: https://gitcode.com/openeuler/stortrace 前往项目官网免费下载&#xff1a;http…

作者头像 李华