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

Java线程池核心参数

DK1.5 中引入了强大的 concurrent 包,其中最常用的莫过了线程池的实现 ThreadPoolExecutor,它给我们带来了极大的方便,但同时,对于该线程池不恰当的设置也可能使其效率并不能达到预期的效果,甚至仅相当于或低于单线程的效率。

ThreadPoolExecutor 类可设置的参数主要有:

  • corePoolSize

核心线程数,核心线程会一直存活,即使没有任务需要处理。当线程数小于核心线程数时,即使现有的线程空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理。

核心线程在 allowCoreThreadTimeout 被设置为 true 时会超时退出,默认情况下不会退出。

  • maxPoolSize
当线程数大于或等于核心线程,且任务队列已满时,线程池会创建新的线程,直到线程数量达到 maxPoolSize。如果线程数已等于 maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。

  • keepAliveTime

当线程空闲时间达到 keepAliveTime,该线程会退出,直到线程数量等于 corePoolSize。如果 allowCoreThreadTimeout 设置为 true,则所有线程均会退出直到线程数量为 0。

  • allowCoreThreadTimeout

是否允许核心线程空闲退出,默认值为 false。

  • queueCapacity

任务队列容量。从 maxPoolSize 的描述上可以看出,任务队列的容量会影响到线程的变化,因此任务队列的长度也需要恰当的设置。

线程池按以下行为执行任务

  1. 当线程数小于核心线程数时,创建线程。
  2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
  3. 当线程数大于等于核心线程数,且任务队列已满
    1. 若线程数小于最大线程数,创建线程
    2. 若线程数等于最大线程数,抛出异常,拒绝任务

系统负载

参数的设置跟系统的负载有直接的关系,下面为系统负载的相关参数:

  • tasks,每秒需要处理的最大任务数量
  • tasktime,处理第个任务所需要的时间
  • responsetime,系统允许任务最大的响应时间,比如每个任务的响应时间不得超过 2 秒。

参数设置

corePoolSize:

每个任务需要 tasktime 秒处理,则每个线程每钞可处理 1/tasktime 个任务。系统每秒有 tasks 个任务需要处理,则需要的线程数为:tasks/(1/tasktime),即 tasks*tasktime 个线程数。假设系统每秒任务数为 100~1000,每个任务耗时 0.1 秒,则需要 100*0.1 至 1000*0.1,即 10~100 个线程。那么 corePoolSize 应该设置为大于 10,具体数字最好根据 8020 原则,即 80% 情况下系统每秒任务数,若系统 80% 的情况下第秒任务数小于 200,最多时为 1000,则 corePoolSize 可设置为 20。

queueCapacity:

任务队列的长度要根据核心线程数,以及系统对任务响应时间的要求有关。队列长度可以设置为 (corePoolSize/tasktime)*responsetime: (20/0.1)*2=400,即队列长度可设置为 400。

队列长度设置过大,会导致任务响应时间过长,切忌以下写法:

LinkedBlockingQueue queue = new LinkedBlockingQueue();

这实际上是将队列长度设置为 Integer.MAX_VALUE,将会导致线程数量永远为 corePoolSize,再也不会增加,当任务数量陡增时,任务响应时间也将随之陡增。

maxPoolSize:

当系统负载达到最大值时,核心线程数已无法按时处理完所有任务,这时就需要增加线程。每秒 200 个任务需要 20 个线程,那么当每秒达到 1000 个任务时,则需要 (1000-queueCapacity)*(20/200),即 60 个线程,可将 maxPoolSize 设置为 60。

keepAliveTime:

线程数量只增加不减少也不行。当负载降低时,可减少线程数量,如果一个线程空闲时间达到 keepAliveTiime,该线程就退出。默认情况下线程池最少会保持 corePoolSize 个线程。

allowCoreThreadTimeout:

默认情况下核心线程不会退出,可通过将该参数设置为 true,让核心线程也退出。

以上关于线程数量的计算并没有考虑 CPU 的情况。若结合 CPU 的情况,比如,当线程数量达到 50 时,CPU 达到 100%,则将 maxPoolSize 设置为 60 也不合适,此时若系统负载长时间维持在每秒 1000 个任务,则超出线程池处理能力,应设法降低每个任务的处理时间 (tasktime)。

IDEA 保姆级安装教程:  http://note.youdao.com/s/Wq2GSETJ  

计算机专业常用毕业设计集合:  http://note.youdao.com/s/PIJHOqnk  


http://www.kler.cn/a/15069.html

相关文章:

  • Label-studio-ml-backend 和YOLOV8 YOLO11自动化标注,目标检测,实例分割,图像分类,关键点估计,视频跟踪
  • 【面试】前端vue项目架构详细描述
  • Unix发展历程的深度探索
  • 智慧环保平台_大数据平台_综合管理平台_信息化云平台
  • Altenergy电力系统 status_zigbee SQL注入漏洞复现(CVE-2024-11305)
  • Diff 算法的误判
  • CA(证书颁发机构)
  • 软件测试概念
  • MATLAB-Lingo求解线性规划问题-奶制品2
  • 车联网V2X通信技术及应用介绍
  • 备忘录设计模式解读
  • 实用的股票接口,股票api收藏(11)
  • 03.预处理
  • 轻量级网络EfficientNetB0,利用迁移学习中的微调技术进行小样本轴承故障诊断(Python代码,带有数据集,训练集集的每类只需10个样本)
  • 【接口自动化测试】selenium旗舰版Web测试理论篇
  • 听我一句劝,别去外包,干了三年,废了....
  • css中的background属性
  • BatchNormalization 介绍
  • 800字带你弄懂Http请求和响应
  • 机器人学一些知识
  • 基于趋动云的 Stable Diffusion Webui 环境搭建
  • 低调且强大——JNPF低代码平台
  • 微服务监控系统选型:Zabbix、Open-Falcon、Prometheus
  • 【LeetCode: 1143. 最长公共子序列 | 暴力递归=>记忆化搜索=>动态规划】
  • SpringBoot启动时自动创建数据库表
  • [Java List类型和Map类型想换转换案例]