线程池种类以及参数设置问题

2023-05-16

JDK1.5中引入了强大的concurrent包,线程池的实现ThreadPoolExcutor。

线程池种类

    通常开发者都是利用Executors提供的通用线程池创建方法,去创建不同配置的线程池,主要区别在于ExecutorService类型或者不同的初始参数。

    Executors目前提供了五种不同的线程池创建配置:

  • newCachedThreadPool(),它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过60秒,则被终止并移出缓存;长时间闲置时,这种线程池并不会消耗什么资源,其内部使用SynchronousQueue作为工作队列;
  • newFixedThreadPool(),创建固定大小的线程池,背后使用的是无界的工作队列,任何时候最多有nThreads个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目nThreads。
  • newSingleThreadExcuteor(),它的特点在于工作线程数目被限制为1,操作一个无界的工作队列,所以保证了所有任务都是被顺序执行的,最多只会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目。
  • newSingleThreadScheduledExcutor()和newScheduleThreadPool(int corePoolSize),创建的是个ScheduledExcutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程。
  • newWorkStealingPool(int parallelism),这是一个经常被人忽略的线程池,Java 8才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序。

阻塞队列(runnableTaskQueue)

  • ArrayBlockingQueue:一个基于数组结构的有界阻塞队列,此队列按照先进先出原则对元素进行排序;
  • LinkedBlockingQueue:一个基于链表结构的阻塞队列,按照先进先出对元素进行排序。吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Excutors.newFixedThreadPool()使用了这个队列;
  • SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。吞吐量要高于LinkedBlockingQueue。静态工厂方法Excutors.newCachedThreadPool()使用了这个队列;
  • PriorityBlockingQueue:一个具有优先级的无界阻塞队列。

系统负载

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

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

ThreadPoolExcutor类可设置的参数有:

1.corePoolSize:

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

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

    每个任务需要tasktime秒处理,则每个线程每秒可以处理1/tasktime个任务。系统每秒有tasks个任务,所以需要的线程数为tasks/(1/tasktime),即tasks*tasktime个线程数。

    假设系统每秒任务数为100-1000,每个任务耗时0.1秒,那么需要10-100个线程, 核心线程数应设置为大于10,具体数字最好根据8020原则,即80%情况下系统每秒任务数,若系统80%情况下每秒任务数小于200,最多时为1000,那么可以设置为20。

2.maxPoolSize:

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

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

3.keepAliveTime:

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

4.allowCoreThreadTimeout:

    是否允许核心线程空闲退出。

5.queueCapacity:

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

    任务队列的长度要根据核心线程数,以及系统对任务响应时间的要求有关。队列长度可以设置为:

(corePoolSize/tasktime)*responsetime:20/0.1*2=400,即队列长度可以设置为400。

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

LinkedBlockingQueue queue=new LinkedBlockingQueue();

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

6.RejectedExcutionHandler:饱和策略

当队列和线程池都满了,说明线程池处于饱和状态,那么必须对新提交的任务采用一种特殊的策略来进行处理。这个策略默认配置是AbortPolicy,表示无法处理新的任务而抛出异常。JAVA提供了4中策略:

  • AbortPolicy:直接抛出异常
  • CallerRunsPolicy:只用调用所在的线程运行任务
  • DiscardOledestPolicy:丢弃队列里最近的一个任务,并执行当前任务
  • DiscardPolicy:不处理,丢弃掉

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

参考:https://blog.csdn.net/zhouhl_cn/article/details/7392607

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程池种类以及参数设置问题 的相关文章

  • spring 事务不生效问题 bmw-jade-route事务配置

    在spring中配置了事务 xff0c 但是没有生效 64 Transactional rollbackFor 61 Exception class public Long insertTicket Ticket ticket List l
  • springboot 拦截器返回json字符串给前端页面

    在intercept中加入以下代码 xff1a private void returnJson HttpServletResponse response String json PrintWriter writer 61 null resp
  • 一句老话:学习贵在坚持,开始学习《Asp.net 程序设计》

    买Asp net书已经一年多了 xff0c 一年来总是为了工作忙忙碌碌 xff0c 书却没有好好看 最近终于可以有时间看书了 xff0c 翻了几页 xff0c 里面有我去年看书的笔记 xff0c 日期是2004 3 12日 看来已经是整整过
  • springboot注解拦截器不生效问题

    今天用springboot写了一个注解拦截器 xff0c 一直不生效 xff0c 网上各种方式我都尝试过了 xff0c 都不起作用 xff0c 找了好久总算知道是什么原因了 我的annotation xff1a 64 Inherited 6
  • springboot pom.xml 配置不替换问题

    今天遇到了一个问题 xff0c 在Pom中配置的变量在编译时没有自动替换 properties文件和 xml文件中的 key xff0c 后来发现原因是因为我在pom里面写了 xff1a 进入starter parent的pom以后发现 x
  • 项目启动报错:Caused by: java.lang.IncompatibleClassChangeError: Implementing class at java.lang.ClassLoad

    项目启动报错 xff1a Caused by java lang IncompatibleClassChangeError Implementing class at java lang ClassLoader defineClass1 N
  • resin服务本地调试

    在项目he project下建两个文件夹 xff0c 分别为resin和webapp 安装的resin放在resin文件夹中 xff0c resin文件夹如下 conf resin xml配置如下 xff1a lt Resin 4 0 co
  • 1机器学习基础—2统计学习方法概论

    一 机器学习基础 1 监督学习一般使用两种类型的目标变量 xff1a 标称型和数值型 在分类算法中目标变量的类型通常是标称型的 xff0c 而在回归算法中通常是连续性的 2 分类和回归都属于监督学习 分类是将实例数据划分到合适的分类中 xf
  • 2感知机

    1 感知机是二类分类的线性分类模型 xff0c 其输入为实例的特征向量 xff0c 输出为实例的类别 xff0c 取 43 1和 1二值 感知机对应于输入空间 xff08 特征空间 xff09 中将实例划分为正负两类的分离超平面 xff0c
  • [leetcode]大可日常打卡1

    344 Reverse String class Solution public String reverseString String s if s 61 61 null s length 61 61 0 return s StringB
  • [leetcode]大可日常打卡2

    804 Unique Morse Code Words 先把所有的字母以及对应的morse code存储到map里面 xff0c 然后对于words的每一个 xff0c 把对应的transformation存储到一个hashmap里面 xf
  • [2017校招]大可打卡1

    1 网易 合唱团 import java util Scanner public class Main public static void main String args Scanner sc 61 new Scanner System
  • [leetcode]大可日常打卡-树

    687 最长同值路径 一开始非常没有思路 看了解析以后 xff0c 找到了思路 xff0c 把长度看作是从一个节点向左右子树延伸出去的两个箭头 xff0c 从下往上遍历 xff0c 后序遍历递归 xff0c 如果箭头上的值等于节点的值 xf
  • 解决:Failed to download metadata for repo ‘base‘: Cannot download repomd.xml: Cannot download repodata

    1 先查看本机的系统信息 root 64 h0436 h0436 zlong cat etc redhat release 2 进入yum repos d root 64 h0436 zlong cd etc yum repos d 3 查
  • [剑指offer]大可日常打卡-树

    8 二叉树的下一个节点 给定一个二叉树和其中的一个结点 xff0c 请找出中序遍历顺序的下一个结点并且返回 注意 xff0c 树中的结点不仅包含左右子结点 xff0c 同时包含指向父结点的指针 思路 xff1a 中序遍历 xff0c 左根右
  • [核心技术36问]1-12

    1 谈谈你对Java平台的理解 xff1f Java是解释执行 xff0c 这句话正确吗 xff1f 典型回答 xff1a Java本身是一种面向对象的语言 xff0c 最显著的特性有两个方面 xff0c 一是所谓的 书写一次 xff0c
  • [计算机网络]一个完整的TCP连接

    当我们向服务器发送HTTP请求 xff0c 获取数据 修改信息时 xff0c 都要建立TCP连接 xff0c 包括三次握手 xff0c 四次挥手 什么是TCP连接 xff1f 为了实现可靠的数据传输 xff0c TCP要在应用进程之间建立传
  • [剑指offer]大可日常打卡-字符串

    5 替换空格 请实现一个函数 xff0c 将一个字符串中的每个空格替换成 20 例如 xff0c 当字符串为We Are Happy 则经过替换之后的字符串为We 20Are 20Happy public class Solution pu
  • [核心技术36问]13-24

    13 谈谈接口和抽象类有什么区别 xff1f 接口和抽象类都是java面向对象设计的两个基础机制 接口是对行为的抽象 xff0c 它是抽象方法的集合 xff0c 利用接口可以实现API定义和实现分离的目的 接口 xff0c 不能实例化 xf
  • [核心技术36问]17.一个线程两次调用start()方法会出现什么情况?谈谈线程的生命周期和状态转移。

    17 一个线程两次调用start 方法会出现什么情况 xff1f 谈谈线程的生命周期和状态转移 Java的线程是不允许启动两次的 xff0c 第二次调用必然会抛出IllegalThreadStateException xff0c 这是一种运

随机推荐

  • 阿里菜鸟内推 一面

    1 自我介绍 2 HashMap和ConcurrentHashMap的区别 xff1f HashMap线程不安全 xff0c ConcurrentHashMap线程安全 HashMap是基于哈希表的Map接口的非同步实现 提供所有可选的映射
  • [核心技术36问]18.什么情况下java程序会产生死锁?如何定位、修复?

    18 什么情况下java程序会产生死锁 xff1f 如何定位 修复 xff1f 死锁是一种特定的程序状态 xff0c 在实体之间 xff0c 由于循环依赖导致彼此一直处于等待之中 xff0c 没有任何个体可以继续前进 死锁不仅仅是在线程之间
  • [核心技术36问]19.Java并发包提供了哪些并发工具类?

    Java并发包提供了哪些并发工具类 xff1f 我们常说的并发工具包就是java util concurrent及其子包 xff0c 集中了Java并发的各种基础工具类 xff0c 其中主要包括以下几个方面 xff1a 提供了比synchr
  • [核心技术36问]20.并发包中的ConcurrentLinkedQueue和LinkedBlockingQueue有什么区别?

    20 并发包中的ConcurrentLinkedQueue和LinkedBlockingQueue有什么区别 xff1f 有时候我们把并发包下面的所有容器都习惯叫做并发容器 xff0c 但是严格来讲 xff0c 类似ConcurrentLi
  • 如何解决:安装linux时报错Operating System not found 怎么办?

    大家出现这个问题了 xff0c 肯定是在网上找资料 其实我也找了很多资料 xff0c 但是呢 xff0c 我找的都没有用 xff0c 后来我自己又从新从头到尾的重新装了几遍 xff0c 然后就发现了问题所在之处 操作步骤 xff1a 1 首
  • 最容易理解的SVM算法原理

    基于最大间隔分隔数据 1 1支持向量与超平面 SVM Support Vector Mac 又称为支持向量机 xff0c 是一种二分类的模型 当然如果进行修改之后也是可以用于多类别问题的分类 支持向量机可以分为线性核和非线性两大类 其主要思
  • [核心技术36问]21.Java并发类库提供的线程池有哪几种?分别有什么特点?

    21 Java并发类库提供的线程池有哪几种 xff1f 分别有什么特点 xff1f 通常开发者都是利用Executors提供的通用线程池创建方法 xff0c 去创建不同配置的线程池 xff0c 主要区别在于ExecutorService类型
  • [剑指offer]大可日常打卡-数组

    4 二维数组中的查找 题目描述 xff1a 在一个二维数组中 xff08 每个一维数组的长度相同 xff09 xff0c 每一行都按照从左到右递增的顺序排序 xff0c 每一列都按照从上到下递增的顺序排序 请完成一个函数 xff0c 输入这
  • 虚拟机类加载机制和new对象的过程

    虚拟机类加载机制 xff1a 类从被加载到虚拟机内存中开始 xff0c 到卸载出内存为止 xff0c 它的整个生命周期包括 xff1a 加载 xff0c 验证 xff0c 准备 xff0c 解析 xff0c 初始化 xff0c 使用和卸载7
  • [剑指offer]大可日常打卡-递归

    43 1 n整数中1出现的次数 题目描述 xff1a 求出1 13的整数中1出现的次数 并算出100 1300的整数中1出现的次数 xff1f 为此他特别数了一下1 13中包含1的数字有1 10 11 12 13因此共出现6次 但是对于后面
  • [剑指offer]大可日常打卡-链表

    6 从尾到头打印链表 题目描述 xff1a 输入一个链表 xff0c 按链表值从尾到头的顺序返回一个ArrayList public class ListNode int val ListNode next 61 null ListNode
  • 8.15 5个题

    1 垃圾回收算法 垃圾回收算法 xff1a 标记 清除 xff1b 复制算法 xff1b 标记 整理 xff1b 分代收集 标记 清除 xff1a 标记所有需要回收的对象 xff0c 在标记完成后统一清除需要回收的对象 效率低且容易产生碎片
  • 8.16 线程池;HTTP;数据库索引

    1 讲一下TCP连接 xff0c 三次握手四次挥手 https blog csdn net hellodake article details 81080415 网路的七层协议是什么 xff1f 物理层 xff0c 数据链路层 xff0c
  • 二分快速幂

    题目描述 xff1a 给定一个double类型的浮点数base和int类型的整数exponent 求base的exponent次方 思路 xff1a 把指数转化为二进制 xff0c 比如8 11 61 8 8 8 1 8 0 11 61 1
  • Spring原理+配置详解

    IOC xff1a inverse of control反转控制 负责创建对象 xff0c 管理对象 xff08 通过依赖注入 xff09 xff0c 配置对象 xff0c 并且管理这些对象的生命周期 以前对象的创建是由开发人员自己维护 x
  • JAVA线程sleep()和wait()区别

    sleep是Thread类的静态方法 xff0c 所以它不能改变对象的锁 xff1b wait是Object的方法 xff1b sleep是会让线程暂停工作一段时间 xff0c 休眠一段时间 xff0c 让出CPU的使用 xff0c 但是不
  • 在idea 中 修改项目结构

    在IDEA 中创建的项目往往我们需要修改一些目录的结构类型 xff0c 正常呢有两种方式 xff01 整理如下 xff1a 一 这种最简单 直接使用 鼠标右键完成 1 在你想要改变结构的目录上 鼠标右键 2 选择 Mark director
  • 数组中重复的数字|||数组中只出现一次的数

    1 找出数组中重复的数字 题目描述 xff1a 在一个长度为n的数组里的所有数字都在0 n 1的范围内 数组中某些数字是重复的 xff0c 但不知道有几个数字重复了 xff0c 也不知道每个数字重复了几次 请找出数组中任意一个重复的数字 例
  • spring aop思想

    spring插件 xff1a STS插件 spring整合junit测试 每一个方法都不需要先获得容器再获得对象了 帮我们创建容器 64 RunWith SpringJUnit4ClassRunner class 指定创建容器时使用哪个配置
  • 线程池种类以及参数设置问题

    JDK1 5中引入了强大的concurrent包 xff0c 线程池的实现ThreadPoolExcutor 线程池种类 通常开发者都是利用Executors提供的通用线程池创建方法 xff0c 去创建不同配置的线程池 xff0c 主要区别