Java 线程池四种拒绝策略_rejected from java.util.concurrent.threadpoolexecu-程序员宅基地

技术标签: java  

jdk1.5版本新增了 JUC 并发包,其中一个包含线程池。

四种拒绝策略:

拒绝策略类型 说明
1 ThreadPoolExecutor.AbortPolicy 默认拒绝策略,拒绝任务并抛出任务
2 ThreadPoolExecutor.CallerRunsPolicy 使用调用线程直接运行任务
3 ThreadPoolExecutor.DiscardPolicy 直接拒绝任务,不抛出错误
4 ThreadPoolExecutor.DiscardOldestPolicy 触发拒绝策略,只要还有任务新增,一直会丢弃阻塞队列的最老的任务,并将新的任务加入

预先配置

配置线程池。

  • 核心线程和最大线程都尽量设置的小一点,分别设置成 1 和 2
  • 阻塞队列设置固定长度的有界队列,长度为 1
  • 线程工厂设置默认线程工厂
// 核心线程数
int corePoolSize = 1;
// 最大线程数
int maximumPoolSize = 2;
// 线程存活时间
long keepAliveTime = 10;
// 线程存活时间单位
TimeUnit unit = TimeUnit.SECONDS;
// 有界队列 遵循 FIFO 原则
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1);
// 线程工厂
ThreadFactory threadFactory = Executors.defaultThreadFactory();

创建线程任务

创建线程任务,一个线程任务执行一秒:

class TaskThread implements Runnable{
                
		private int i;

		public TaskThread(int i) {
			this.i = i;
		}

		@Override
		public void run() {
			try {
				TimeUnit.SECONDS.sleep(2);
				System.out.println("执行任务:" + i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

拒绝策略一:AbortPolicy

默认拒绝策略,拒绝任务并抛出任务

// 拒绝策略 默认拒绝策略,拒绝任务并抛出异常:
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize,
				maximumPoolSize,
				keepAliveTime,
				unit,
				workQueue,
				threadFactory,
				handler);
		for (int i = 1; i <= 5; i++) {
			try {
				threadPool.execute(new TaskThread(i));
			} catch (Exception e) {
				System.out.println("【任务" + i + "】报错:" + e.getMessage());
			}

		}

输出

【任务】4报错:Task com.test.controller.ThreadPoolController$TaskThread@5c0369c4 rejected from java.util.concurrent.ThreadPoolExecutor@50675690[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
【任务】5报错:Task com.test.controller.ThreadPoolController$TaskThread@31b7dea0 rejected from java.util.concurrent.ThreadPoolExecutor@50675690[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
执行任务:1
执行任务:3
执行任务:2

最大线程数 + 阻塞队列 = 3,执行到4,5的时候就抛出错误。这里需要用 try catch 捕获异常。任务1、2、3正常执行。

如果提交的任务都要执行,可以将抛出的错误任务存入在redis中,然后定时从redis中获取任务,再提交执行。

拒绝策略二:CallerRunsPolicy

调用线程运行多余的任务。

更换拒绝策略,将上面的 AbortPolicy 换成 CallerRunsPolicy

RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

执行任务,输出:

执行任务:1
执行任务:4
执行任务:3
执行任务:2
执行任务:5

最大线程数 + 阻塞队列 = 3,多余的任务还是继续被执行。

拒绝策略三:DiscardPolicy

拒绝任务,不会抛出错误。
更换策略,将CallerRunsPolicy 换成DiscardPolicy:

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

执行任务,输出:

执行任务:1
执行任务:3
执行任务:2

多余的线程任务提交被拒绝,而只执行最大线程数 + 阻塞队列 数量的任务,并且不会抛出错误。

拒绝策略四:DiscardOldestPolicy

只要还有任务新增,一直会丢弃阻塞队列的最老的任务,并将新的任务加入到阻塞队列中
更换策略,将DiscardPolicy 换成DiscardOldestPolicy:

RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardOldestPolicy();

执行任务,输出:

执行任务:3
执行任务:1
执行任务:5

任务的执行顺序是 核心线程数 —> 阻塞队列 —> 最大线程数,其中任务1,任务3提交成功。

  • 任务2因为在阻塞队列中,
  • 后面的任务4把任务2挤掉,
  • 任务5又把任务4挤掉,所以最后执行的是任务5。

总结

本文介绍了线程四种拒绝策略,当工作任务大于最大线程 + 阻塞队列会执行阻塞队列。

  • AbortPolicy 默认策略,拒绝任务,并抛出异常
  • CallerRunsPolicy 调用线程执行对于的任务
  • DiscardPolicy 拒绝任务,不会抛出异常
  • DiscardOldestPolicy 有多余的任务,把阻塞队列最老的任务丢弃,放入新的任务,直到没有新的任务。
    如果觉得文章对你有帮助的话,请点个赞吧!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42700121/article/details/124442422

智能推荐

掌握Python8种绘图类型带你深入时间序列数据分析_python中序列类型图表-程序员宅基地

文章浏览阅读639次。时间序列数据是许多领域的核心,从金融市场到气象学,都需要对时间序列数据进行分析和可视化。_python中序列类型图表

️创意网页:生日快乐!穿越奇妙时光的温暖庆祝(HTML+CSS+JS)简单好用_网页制作生日快乐-程序员宅基地

文章浏览阅读3.2k次,点赞7次,收藏51次。️创意网页:生日快乐!穿越奇妙时光的温暖庆祝(HTML+CSS+JS)简单好用_网页制作生日快乐

由投影仪到智能会议平板,经历怎样的发展过程?_交互智能平板的发展历程-程序员宅基地

文章浏览阅读267次。皓丽作为智能会议平板市场早期开拓者,从抢占行业先机,到突破简单的显示和交互的束缚,进化成更为智能的产品,再到顺势而为,凭借强大的供应链体系和研发实力实现大尺寸交互平板产品的不断革新,不仅加强产品自身的创新,构建了显示驱动、工程制造、品质管控的核心竞争力,更整合软硬件优势,实现“生态型”的创新,打通上下游,走向细分化的场景运营,引领整个会议平板市场持续向上发展。,刷新行业配置新高,进一步在技术上引领行业,同时深入各行各业,针对金融、医疗、零售等不同场景定制解决方案,覆盖不同类型、不同场景下的用户需求。..._交互智能平板的发展历程

Android自动化测试(UiAutomator)简要介绍_android test uianimator-程序员宅基地

文章浏览阅读804次。Android自动化测试(UiAutomator)简要介绍_android test uianimator

32位16进制浮点数转化成10进制数-程序员宅基地

文章浏览阅读2.9k次。为什么80%的码农都做不了架构师?>>> ..._16进制转换10进制浮点数

回溯算法,模板,拔河,旅行商,连续邮资问题题解_python 实现连续邮资问题-程序员宅基地

文章浏览阅读468次,点赞3次,收藏9次。回溯算法模板,拔河问题,旅行商问题,连续邮资问题_python 实现连续邮资问题

随便推点

studiolibrary安装_studio library插件下载-maya动作插件studio library下载v2.6.3 免费版-西西软件下载...-程序员宅基地

文章浏览阅读2.5k次。studio library插件是一款为maya用户提供的动作库插件,你可以通过这款插件来管理maya动作库,它还可以通过插值的方式动态调整 Pose,动画,并且有多种拼接方式。支持动画克隆,可以将 A 角色上的动画克隆到 B 角色上,并且支持选择集,即仅适配部分动画或 Pose。使用方法:1选中所有需要复制动画的骨骼2打开studio library 插件, 在左边栏按右键按右键,选new---..._studiolibrary怎么安装maya

Kafka集群安装部署(超详细操作演示)—— Linux_linux上搭建kafka集群搭建详细步骤-程序员宅基地

文章浏览阅读3k次,点赞8次,收藏12次。Kafka集群安装部署(超详细操作演示)—— Linux_linux上搭建kafka集群搭建详细步骤

css地球旋转_css旋转地球-程序员宅基地

文章浏览阅读453次。<!doctype html><html><head><meta charset="utf-8"><title>css地球旋转</title><style>* {margin:0; padding:0; border:0;}.rotateBox {width:200px; height:200px; margin:100px; }.rotateBoxImg {width:200px; height:200p_css旋转地球

Spring框架下利用AbstractRoutingDataSource配置多数据源_abstractroutingdatasource 如何注入datasource-程序员宅基地

文章浏览阅读907次。首先看Druid数据库多数据源DemoSpring的多数据源支持---AbstractRoutingDataSource,AbstractRoutingDataSource定义了抽象的determineCurrentLookupKey方法,子类实现此方法,来确定要使用的数据源public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean { protec_abstractroutingdatasource 如何注入datasource

常见Dos攻击原理及防护(死亡之Ping、Smurf、Teardown、LandAttack、SYN Flood)_死亡ping攻击与哪种攻击类似-程序员宅基地

文章浏览阅读2w次,点赞15次,收藏84次。DoS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻击,其目的是使计算机或网络无法提供正常的服务。最常见的DoS攻击有计算机网络带宽攻击和连通性攻击。 DoS攻击是指故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源,目的是让目标计算机或网络无法提供正常的服务或资源访问,使目标系统服务系统停止响应甚至崩溃,而在此攻击中并不_死亡ping攻击与哪种攻击类似

软件工程期末试题及答案(史上最全)_软件工程期末考试题库-程序员宅基地

文章浏览阅读632次,点赞21次,收藏15次。答:软件再工程是运用逆向工程、重构等技术,在充分理解原有软件的基础上,进行分解、综合,并重新构建软件,用以提高软件的可理解性、可维护性、可复用性或演化性。64.模块的控制范围包括它本身及它所有的从属模块,模块的作用范围是指模块内一个判定的作用范围,凡是受到这个判定影响的所有模块都属于这个判定的作用范围,理想的情况是( A)106. ( C )是把对象的属性和操作结合在一起,构成一个独立的对象,其内部信息对外界是隐蔽的,外界只能通过有限的接口与对象发生联系。C) 内容耦合,公共环境耦合,控制耦合,数据耦合。

推荐文章

热门文章

相关标签