关于如何合理设置线程池参数解决方案

news/2024/7/7 23:09:16

关于如何合理设置线程池参数解决方案(ThreadPoolExecutor)

线程池参数有哪些

我们直接来看构造方法

...
public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6,
			ThreadFactory var7, RejectedExecutionHandler var8) {
		this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
		this.mainLock = new ReentrantLock();
		this.workers = new HashSet();
		this.termination = this.mainLock.newCondition();
		if (var1 >= 0 && var2 > 0 && var2 >= var1 && var3 >= 0L) {
			if (var6 != null && var7 != null && var8 != null) {
				this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
				//核心线程数
				this.corePoolSize = var1;
				//最大线程数
				this.maximumPoolSize = var2;
				//工作队列
				this.workQueue = var6;
				//线程存活时间
				this.keepAliveTime = var5.toNanos(var3);
				//线程工厂
				this.threadFactory = var7;
				//拒绝策略
				this.handler = var8;
			} else {
				throw new NullPointerException();
			}
		} else {
			throw new IllegalArgumentException();
		}
	}
	...

根据构造方法我们可以观察有7个参数
最最重要的三个参数,该解决方案也是围绕着这三个参数进行展开。
corePoolSize
maximumPoolSize
workQueue

美团是这么做的

大家想一想,美团饭点时的业务峰值和凌晨的业务峰值一样吗?这就要求在高峰期的时候,处理业务的线程能覆盖住业务量(当然nginx负载均衡、或其它限流框架也能做到这点,这里仅讨论在一个服务内如何做到伸缩自如),所以根据业务峰去做出调整即为合理的解决方案。

线程池处理任务流程

在这里插入图片描述
根据上面的流程图,我们只需要在三个关键点去做到动态配置即可,下面一一列举

动态设置corePoolSize

ThreadPoolExecutor里面给我们提供了setCorePoolSize(int var1)方法,能让我们在线程池运行的过程中去动态设置核心线程数。

源码解析

public void setCorePoolSize(int var1) {
		if (var1 < 0) {
			throw new IllegalArgumentException();
		} else {
			int var2 = var1 - this.corePoolSize;
			this.corePoolSize = var1;
			if (workerCountOf(this.ctl.get()) > var1) {
				this.interruptIdleWorkers();
			} else if (var2 > 0) {
				int var3 = Math.min(var2, this.workQueue.size());

				while (var3-- > 0 && this.addWorker((Runnable) null, true) && !this.workQueue.isEmpty()) {
					;
				}
			}

		}
	}

步骤:
1.首先判断传进来的var1是否符合要求、不符合直接抛出异常。

2.将corePoolSize 设置为var1。

3.workerCountOf(this.ctl.get())这个方法就是判断当前线程池正在工作的线程数,判断是否大于var1(ctl这个属性通过高位、低位来维护了线程数量,还维护了线程池的运行状态,为什么这么使用,因为在线程池的大多数方法中都需要去获取线程池工作线程的数量以及状态,AtomicInteger ctl本身是一个线程安全的对象),如果大于var1,则像正在工作的线程发出中断请求,以回收线程。

4.如果小于var1,会将var2(var1与旧corePoolSize 的差值)会跟现在阻塞队列的长度进行比较,获取比较小的那个值var3,取出阻塞队列var3个任务执行。

5.这样就完成了对一个正在运行的线程池动态改变corePoolSize 的操作。

动态设置maximumPoolSize

ThreadPoolExecutor里面给我们提供了setMaximumPoolSize(int var1)方法,能让我们在线程池运行的过程中去动态设置最大线程数。

源码解析

public void setMaximumPoolSize(int var1) {
		if (var1 > 0 && var1 >= this.corePoolSize) {
			this.maximumPoolSize = var1;
			if (workerCountOf(this.ctl.get()) > var1) {
				this.interruptIdleWorkers();
			}

		} else {
			throw new IllegalArgumentException();
		}
	}

这个相对操作核心线程来说就比较简单了

步骤:
1.当然还是先判断传入的参数符不符合规范,不符合直接抛出异常

2.将maximumPoolSize 设置为var1

3.判断当前工作线程数是否大于var1,大于则向当前工作线程发出中断请求,回收线程

重写workQueue

因为阻塞队列中的capacity也就是初始化队列的长度使用final字符来进行修饰,所以当队列长度一旦确定就不可更改
美团技术团队的解决方法是将LinkedBlockingQueue重写了,也就是把capacityfinal去掉,达到了通过改变capacity的值来达到控制阻塞队列长度的目的

创作不易,转载请标注!!!


http://lihuaxi.xjx100.cn/news/955256.html

相关文章

Linux系统的稳定性优势有哪些

Linux系统的一些优点 在线使用Linux服务器为您提供了如此多的优势。其实它的优势比其劣势更重&#xff0c;其中一些是&#xff1a; 1、提供稳定性&#xff0c;因为基于Linux的服务器不容易崩溃。在遇到碰撞的情况下&#xff0c;整个系统都不受影响。 2、降低对潜在的系统威胁…

【2023】DevOps、SRE、运维开发面试宝典之Istio相关面试题

文章目录 1、什么是Service Mesh服务网格?2、微服务治理网格的特点?3、Istio服务网格的组件有那些?4、Istio常见的资源控制器有哪些?5、应用程序接入Sidecar6、Istio与K8S集成架构7、Istio Gateway网关资源控制器8、Istio VirtualService虚拟服务资源9、Istio DestinationR…

Gitlab普通用户转管理员

GitLab是常用的分部式代码库版本开源软件&#xff0c;默认系统中只有一个管理员。在工作中&#xff0c;如果有多个项目&#xff0c;则需要多个管理员分别管理各个的代码仓库&#xff0c;需要把多个普通用户配置成管理员&#xff0c;在Gitlab页面上&#xff0c;不能直接通过操作…

消息队列 面试题 整理

消息队列 为什么要使用消息队列&#xff1f; 异步解耦&#xff1a;关注的是通知而非处理。 流量削峰&#xff1a;将短时间内高并发的请求持久化&#xff0c;然后逐步处理&#xff0c;削平高峰期的请求。 日志收集&#xff1a; 事务最终一致性 系统间的消息通信方式&#xff…

测开:vue入门(1)

目录 一、背景 二、介绍 三、创建项目 3.1 创建vue项目 方式二&#xff1a;直接在html页面中&#xff0c;引入vue 3.2 直接在html页面中&#xff0c;引入vue 3.2.1 引入在线的vue&#xff08;方式一&#xff09; 3.2.2 将vue 下载到本地&#xff08;方式二&#xff09; …

第 46 届世界技能大赛浙江省选拔赛“网络安全“项目B模块任务书

第46届世界技能大赛浙江省选拔赛"网络安全"项目B模块&#xff08;网络安全事件响应、数字取证调查&#xff09;第46届世界技能大赛浙江省选拔赛"网络安全"项目B模块2.1 第一部分 事件响应2.2 第二部分 数字取证调查2.3 第三部分 应用程序安全第46届世界技能…

Shader(光线追踪二)

辐射度量Irradiance &#xff08;入射在表面点上的单位面积的能量&#xff09;Radiance&#xff08;单位立体角、单位投影面积发射、反射、传输或接收的能量&#xff09;BRDF(从每个入射方向到每个输出方向反射了多少光)1.反射方程2.渲染方程期望p&#xff08;x&#xff09;》P…

Kakfa详解(一)

kafka使用场景 canal同步mysqlelk日志系统业务系统Topic kafka基础概念 Producer: 消息生产者&#xff0c;向kafka发送消息Consumer: 从kafka中拉取消息消费的客户端Consumer Group: 消费者组&#xff0c;消费者组是多个消费者的集合。消费者组之间互不影响&#xff0c;所有…