Java多线程4种拒绝策略
文章目录
- 一、简介
- 二、AbortPolicy拒绝策略
- A. 概述
- B. 拒绝策略实现原理
- C. 应用场景
- D. 使用示例
- 三、CallerRunsPolicy拒绝策略
- A. 概述
- B. 拒绝策略实现原理
- C. 应用场景
- D. 使用示例
- 四、DiscardPolicy拒绝策略
- A. 概述
- B. 拒绝策略实现原理
- C. 应用场景
- D. 使用示例
- 五、DiscardOldestPolicy拒绝策略
- A. 概述
- B. 拒绝策略实现原理
- C. 应用场景
- D. 使用示例
- 六、总结
- 各种拒绝策略的特点和适用场景
一、简介
在Java多线程编程中,我们通常使用线程池来管理和调度任务。线程池由一组预先创建的线程组成,可以重复利用这些线程来执行多个任务,避免频繁地创建和销毁线程而带来的性能开销。
当线程池中的任务队列已满且无法再接受新的任务时,就需要采取拒绝策略来处理这种情况。拒绝策略定义了当无法再接受新的任务时如何处理这些被拒绝的任务。
Java提供了四种常见的拒绝策略:
-
AbortPolicy(抛出异常):默认的拒绝策略。当任务无法被提交给线程池时,会直接抛出RejectedExecutionException异常。
-
CallerRunsPolicy(调用者运行):当任务无法被提交给线程池时,会由提交任务的线程自己执行该任务。
-
DiscardPolicy(直接丢弃):当任务无法被提交给线程池时,直接丢弃该任务,没有任何提示或处理。
-
DiscardOldestPolicy(丢弃最旧任务):当任务无法被提交给线程池时,会丢弃队列中最早的一个任务,然后尝试再次提交当前任务。
二、AbortPolicy拒绝策略
A. 概述
AbortPolicy是ThreadPoolExecutor的默认拒绝策略,当任务无法被提交给线程池时,会直接抛出RejectedExecutionException异常。
B. 拒绝策略实现原理
实现RejectedExecutionHandler接口,在rejectedExecution方法中抛出异常。
public class AbortPolicy implements RejectedExecutionHandler {public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());}
}
C. 应用场景
适用于对任务提交失败要求敏感的场景,需要明确知道任务是否被接受并执行。
D. 使用示例
当线程池的任务队列和线程队列都已满的情况下执行决绝策略
public class Task implements Runnable {private final int index;public Task(int index) {this.index = index;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ":" + index);}
}public class Main {public static void main(String[] args) {// 创建线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1, 0L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(1),new ThreadPoolExecutor.AbortPolicy());try {// 提交任务threadPool.execute(new Task(1));threadPool.execute(new Task(2));threadPool.execute(new Task(3));} catch (RejectedExecutionException e) {e.printStackTrace();} finally {// 关闭线程池threadPool.shutdown();}}
}
三、CallerRunsPolicy拒绝策略
A. 概述
CallerRunsPolicy是一种简单的拒绝策略,当任务无法被提交给线程池时,会由提交任务的线程自己执行该任务。
B. 拒绝策略实现原理
实现RejectedExecutionHandler接口,在rejectedExecution方法中使用提交任务的线程来执行任务。
public class CallerRunsPolicy implements RejectedExecutionHandler {public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {r.run();}}
}
C. 应用场景
适用于对任务提交失败要求较低的场景,通过调用线程来执行任务,避免任务丢失。
D. 使用示例
public class Task implements Runnable {private final int index;public Task(int index) {this.index = index;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ":" + index);}
}
public class Main {public static void main(String[] args) {// 创建线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1, 0L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(1),new ThreadPoolExecutor.CallerRunsPolicy());try {// 提交任务threadPool.execute(new Task(1));threadPool.execute(new Task(2));threadPool.execute(new Task(3));} catch (RejectedExecutionException e) {e.printStackTrace();} finally {// 关闭线程池threadPool.shutdown();}}
}

四、DiscardPolicy拒绝策略
A. 概述
DiscardPolicy是一种简单的拒绝策略,当任务无法被提交给线程池时,会直接丢弃该任务,没有任何提示或处理。
B. 拒绝策略实现原理
实现RejectedExecutionHandler接口,在rejectedExecution方法中不做任何操作,即丢弃任务。
public class DiscardPolicy implements RejectedExecutionHandler {public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {// Do nothing, discard the task}
}
C. 应用场景
适用于对任务提交失败不敏感的场景,对任务丢失没有特殊要求。
D. 使用示例
public class Task implements Runnable {private final int index;public Task(int index) {this.index = index;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ":" + index);}
}
public class Main {public static void main(String[] args) {// 创建线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1, 0L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(1),new ThreadPoolExecutor.DiscardOldestPolicy());try {// 提交任务threadPool.execute(new Task(1));threadPool.execute(new Task(2));threadPool.execute(new Task(3));} catch (RejectedExecutionException e) {e.printStackTrace();} finally {// 关闭线程池threadPool.shutdown();}}
}

五、DiscardOldestPolicy拒绝策略
A. 概述
DiscardOldestPolicy是一种拒绝策略,当任务无法被提交给线程池时,会丢弃最早的一个任务,然后尝试再次提交。
B. 拒绝策略实现原理
实现RejectedExecutionHandler接口,在rejectedExecution方法中从队列中获取最早的任务并丢弃,再次提交当前任务。
public class DiscardOldestPolicy implements RejectedExecutionHandler {public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {e.getQueue().poll();e.execute(r);}}
}
C. 应用场景
适用于对新任务优先级比较高的场景,可以丢弃旧的任务以保证及时处理新任务。
D. 使用示例
public class Task implements Runnable {private final int index;public Task(int index) {this.index = index;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ":" + index);}
}
public class Main {public static void main(String[] args) {// 创建线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1, 0L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(2),new ThreadPoolExecutor.DiscardOldestPolicy());try {// 提交任务threadPool.execute(new Task(1));threadPool.execute(new Task(2));threadPool.execute(new Task(3));threadPool.execute(new Task(4));} catch (RejectedExecutionException e) {e.printStackTrace();} finally {// 关闭线程池threadPool.shutdown();}}
}

六、总结
各种拒绝策略的特点和适用场景
- AbortPolicy:对任务提交失败要求敏感,需要明确知道任务是否被接受并执行。
- CallerRunsPolicy:对任务提交失败要求较低,通过调用线程来执行任务,避免任务丢失。
- DiscardPolicy:对任务提交失败不敏感,对任务丢失没有特殊要求。
- DiscardOldestPolicy:适用于新任务优先级高,丢弃旧任务以保证及时处理新任务。
相关文章:
Java多线程4种拒绝策略
文章目录 一、简介二、AbortPolicy拒绝策略A. 概述B. 拒绝策略实现原理C. 应用场景D. 使用示例 三、CallerRunsPolicy拒绝策略A. 概述B. 拒绝策略实现原理C. 应用场景D. 使用示例 四、DiscardPolicy拒绝策略A. 概述B. 拒绝策略实现原理C. 应用场景D. 使用示例 五、DiscardOldes…...
MySQL的MHA
1.什么是 MHA MHA(MasterHigh Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的过…...
Java实现链表
在Java中,可以使用类来定义链表的节点,并使用引用数据类型(即类名)来模拟指针进而构建链表。下面是一个简单的示例。 首先,创建一个节点类 Node,它包含一个值和指向下一个节点的引用: public …...
SpringCloud Alibaba(2021.0.1版本)微服务-OpenFeign以及相关组件使用(保姆级教程)
💻目录 前言一、简绍二、代码实现1、搭建服务模块1.1、建立父包1.2、建立两个子包(service-order、service-product)1.3、添加util 工具类 2、添加maven依赖和yml配置文件2.1、springcloud-test父包配置2.2、服务模块配置2.2.1、service-orde…...
豆制品废水处理设备源头厂家方案
豆制品废水处理设备源头厂家方案 豆制品生产过程中产生的废水含有有机物、悬浮物、油脂等污染物,需要经过合理的处理才能达到排放标准或循环再利用。以下是一个可能的豆制品废水处理设备及方案: 1.初步处理: 格栅:用于去除大颗粒的…...
lnmp环境搭建
文章目录 一、环境信息二、LNMP环境搭建2.1 准备编译环境2.2 nginx安装2.3 mysql安装2.4 php安装2.5 nginx配置2.6 mysql配置2.7 配置php 三、常见问题3.1 安装其它版本的nginx服务3.2 php版本过低 一、环境信息 操作系统:公共镜像CentOS 7.8 64位 本文的部署配置…...
全球研发中心城市专题协商会课题调研组莅临麒麟信安考察指导
9月7日上午,长沙市政协党组副书记、副主席石长松,市委统战部副部长、市工商联党组书记何惠风,市政协研究室主任郑志华,市工商联党组成员、副主席王婧等领导一行莅临麒麟信安开展全球研发中心城市专题协商会课题调研,麒…...
ZeroTier客户端连接服务器
ZeroTier客户端连接服务器 下载客户端 https://www.zerotier.com/download/加入新的网络(例如d5e04297a16fa690,由管理员提供)管理员授权并告知服务器IP测试连接:ping 服务器IP使用putty, pycharm, vscode等工具连接即可 官方文…...
NFT Insider#106:The Sandbox 与 Light Matrix 以及鲁比尼拳击场达成战略合作
引言:NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据,艺术新闻类,游戏新闻类,虚拟世界类&#…...
【猿灰灰赠书活动 - 04期】- 【分布式统一大数据虚拟文件系统——Alluxio原理、技术与实践】
👨💻本文专栏:赠书活动专栏(为大家争取的福利,免费送书) 👨💻本文简述:博文为大家争取福利,与机械工业出版社合作进行送书活动 👨…...
前端element表格导出excel
一:安装依赖 npm install xlsx file-saver --save二:在组件中导入 import FileSaver from file-saver import XLSX from xlsx三:给对应表格添加id,绑定方法 <el-table idtableDom> <el-button click"exportExc…...
React中的类组件和函数组件(详解)
React的核心思想就是组件化,相对于Vue来说,React的组件化更加灵活和多样。主要可以分为两大类:函数组件,类组件,这两大类组件的名称必须是大写字母开头 一、函数组件 函数组件通常是function进行定义的函数࿰…...
1987-2021年全国31省专利申请数和授权数
1987-2021年全国31省国内三种专利申请数和授权数 1、时间:1987-2021年 2、来源:整理自国家统计局、科技统计年鉴、各省年鉴 3、范围:31省市 4、指标:国内专利申请受理量、国内发明专利申请受理量、国内实用新型专利申请受理量…...
欧洲云巨头OVHcloud收购边缘计算专家 gridscale
边缘计算社区近日获悉,欧洲云巨头OVHcloud已进入全面收购德国公司 gridscale 的谈判,该公司是一家专门从事超融合基础设施的软件提供商。 此次战略收购将标志着 OVHcloud 的另一个重要里程碑,使该集团能够显着加速其地理部署,并进…...
java从入门到起飞(八)——循环和递归
文章目录 Java循环1. 什么是循环?1.1 为什么需要循环?1.2 循环的分类 2. Java中的循环结构2.1 for循环2.2 while循环2.3 do-while循环 3. 循环控制语句3.1 break语句3.2 continue语句 4. 总结 Java递归1. 什么是递归2. 递归的原理3. 递归的实现4. 递归的…...
架构师成长之路|Redis实现延迟队列的三种方式
延迟队列实现 基于监听key过期实现的延迟队列实现,这里需要继承KeyspaceEventMessageListener类来实现监听redis键过期 public class KeyExpirationEventMessageListener extends KeyspaceEventMessageListener implementsApplicationEventPublisherAware {private static f…...
51单片机智能电风扇控制系统proteus仿真设计( 仿真+程序+原理图+报告+讲解视频)
51单片机智能电风扇控制系统仿真设计( proteus仿真程序原理图报告讲解视频) 讲解视频1.主要功能:2.仿真3. 原理图4. 程序代码5.设计报告6. 设计资料内容清单 51单片机智能电风扇控制系统仿真设计( proteus仿真程序原理图报告讲解视频) 仿真图…...
【设计模式】Head First 设计模式——工厂方法模式 C++实现
设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 设计思想 定义一个用于创建对象的接口,让子…...
【爬虫】7.2. JavaScript动态渲染界面爬取-Selenium实战
JavaScript动态渲染界面爬取-Selenium实战 爬取的网页为:https://spa2.scrape.center,里面的内容都是通过Ajax渲染出来的,在分析xhr时候发现url里面有token参数,所有我们使用selenium自动化工具来爬取JavaScript渲染的界面。 fr…...
c语言实训心得3篇集合
c语言实训心得体会一: 在这个星期里,我们专业的学生在专业老师的带领下进行了c语言程序实践学习。在这之前,我们已经对c语言这门课程学习了一个学期,对其有了一定的了解,但是也仅仅是停留在了解的范围,对里…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
