我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么评估一个线程池需要设置多少个线程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么评估一个线程池需要设置多少个线程

这篇文章主要介绍“怎么评估一个线程池需要设置多少个线程”,在日常操作中,相信很多人在怎么评估一个线程池需要设置多少个线程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么评估一个线程池需要设置多少个线程”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1、线程池基本工作原理与面试指南

1.1 java线程池的核心属性

JAVA 线程池的核心属性如下:

  • int corePoolSize

核心线程数

  • int maximumPoolSize

线程池最大线程数

  • long keepAliveTime

线程保持活跃的时间

  • TimeUnit unit

keepAliveTime 的时间单位

  • BlockingQueue< Runnable > workQueue

任务挤压队列

  • ThreadFactory threadFactory

线程创建工厂类

  • RejectedExecutionHandler handler

拒绝策略

1.2 向线程池提交任务时线程创建过程

那当用户向线程池提交一个任务的时候,线程池会如何创建线程呢?

首先线程池会判断当前已创建的线程是否小于 corePoolSize  (核心线程数),如果小于,则无论已创建的线程是否空闲,都会选择创建一个新的线程来执行该任务,直到已创建的线程等于核心线程数。

当线程池中已创建的线程数等于核心核心线程数时,用户继续向线程池提交任务时,此时会先判断任务队列是否已满:

1)如果任务队列未满,则将任务放入队列中。

2)如果任务队列已满,则判断当前线程数量是否超过了最大线程数量,如果未超过,则创建一个新的线程来执行该任务,如果线程池已创建的线程数量等最大线程数,则执行拒绝策略。

温馨提示:所以如果线程池使用的队列无界队列,最大线程数会变的没有意义。

1.3 线程池的拒绝策略、使用场景

JUC 默认提供了如下拒绝策略:

  • AbortPolicy

拒绝,直接抛出 RejectedExecutionException,默认值。

  • CallerRunsPolicy

由调用线程直接运行任务的 run 方法,即异步转同步。

  • DiscardOldestPolicy

丢弃任务队列中最先进入的任务。

  • DiscardPolicy

拒绝了,就不执行,“当没事人事”样。

拒绝策略触发的条件:线程池使用的是有界任务队列时,才有可能被触发,当队列已满,并且线程池创建的线程已经达到了最大允许的线程池时。

默认情况下,通常使用 AbortPolicy 即可。

CallerRunsPolicy  异步转同步在出现拒绝的情况下其实意义不大,没有想出其合适的场景,因为需要执行拒绝策略的时候,已经处理变慢了,再同步执行任务,只会增加服务器的负载,不利于恢复问题。

DiscardOldestPolicy 这种策略,通常用于类似记录轨迹,偶尔丢失点数据没关系,但希望最新的数据能得到保存。

DiscardPolicy 策略,通常用来异步打印日志,直接忽略不执行,期望保存旧的数据。

1.4 如何选择阻塞队列

阿里内部的开源规范明确禁止使用无界队列,如果使用无界队列,任务会不受限制的往线程池中提交,有可能造成内存溢出。

如果使用无界队列,最大线程数这个参数将会失效,因为永远也不会创建多于核心线程数量的线程。

1.5 线程池工厂有何实际用处

ThreadFactory  threadFactory,线程池工厂,在使用线程池时,强烈推荐使用自己定义的线程工厂,这样能为线程池中的线程进行命名,方便跟大家使用 jsatck  命令查看线程栈时,能快速识别对应的线程。

1.6 keepAliveTime参数的作用

keepAliveTime :通俗点来说,这个参数表示线程的最大空闲时间,即如果线程没有在执行任务,能存活的时间。

默认情况下,该参数只针对超过核心线程数(corePoolSize)  的线程,可通过将allowCoreThreadTimeOut设置为true,则核心线程数也会因为空闲而被关闭。

2、如何为线程池设置合适的线程

目前根据我看过的一些开源框架,设置多少个线程数量通常是根据应用的类型:IO密集型、CPU密集型。

  • IO密集型通常设置为2n+1,其中n为CPU核数

  • CPU密集型通常设置为 n+1。

实际情况往往复杂的多,并不会按照这个进行设置,上面的公式通常适合框架类,例如netty,dubbo这种底层通讯框架通常会参考上述标准进行设置。

关于在实际业务开发中,如何为一个线程池设置合适的线程呢?

其实对于IO密集型类型的应用,网上还有一个公式:线程数 = CPU核心数/(1-阻塞系数)

引入了阻塞系数的概念,一般为0.8~0.9之间,

在我们的业务开发中,基本上都是IO密集型,因为往往都会去操作数据库,访问redis,es等存储型组件,涉及到磁盘IO,网络IO。

那什么场景下是CPU密集型呢?纯计算类,例如计算圆周率的位数,当然我们基本接触不到。

IO密集型,可以考虑多设置一些线程,主要目的是可以增加IO的并发度,CPU密集型不宜设置过多线程,因为是会造成线程切换,反而损耗性能。

接下来我们以一个实际的场景来说明如何设置线程数量。

一个4C8G的机器上部署了一个MQ消费者,在RocketMQ的实现中,消费端也是用一个线程池来消费线程的,那这个线程数要怎么设置呢?

如果按照 2n + 1 的公式,线程数设置为 9个,但在我们实践过程中发现如果增大线程数量,会显著提高消息的处理能力,说明 2n + 1  对于业务场景来说,并不太合适。

如果套用 线程数 = CPU核心数/(1-阻塞系数) 阻塞系数取 0.8 ,线程数为 20 。阻塞系数取  0.9,大概线程数40,20个线程数我觉得可以。

如果我们发现数据库的操作耗时比较多,此时可以继续提高阻塞系数,从而增大线程数量。

那我们怎么判断需要增加更多线程呢?其实可以用jstack命令查看一下进程的线程栈,如果发现线程池中大部分线程都处于等待获取任务,则说明线程够用,如下图所示:

怎么评估一个线程池需要设置多少个线程

如果大部分线程都处于运行状态,可以继续适当调高线程数量。

到此,关于“怎么评估一个线程池需要设置多少个线程”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么评估一个线程池需要设置多少个线程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java多线程该设置多少个线程

本篇内容主要讲解“java多线程该设置多少个线程”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java多线程该设置多少个线程”吧!我们在使用线程池的时候,会有两个疑问点: 线程池的线程数量设置过
2023-06-16

java中怎么实现一个线程池

本篇文章为大家展示了java中怎么实现一个线程池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new
2023-06-20

C++怎么实现一个简单的线程池

本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容
2023-06-30

java多个线程怎么共享一个变量

Java中多个线程可以通过共享变量来实现线程之间的通信和共享数据。以下是几种常见的实现方式:使用共享变量作为实例变量:将共享变量定义为一个对象的实例变量,然后多个线程可以通过该对象来访问和修改共享变量。public class Shared
2023-10-27

python线程池ThreadPoolExecutor怎么传单个参数和多个参数

这篇文章主要介绍了python线程池ThreadPoolExecutor怎么传单个参数和多个参数的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇python线程池ThreadPoolExecutor怎么传单个参数
2023-07-05

Java中怎么实现一个多线程程序

Java中怎么实现一个多线程程序,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java多线程程序设计详细解析一、理解Java多线程Java多线程是这样一种机制,它允许在程序中并
2023-06-17

c++中一个对象怎么运行多个线程

在C++中,一个对象可以通过创建多个线程来同时执行多个任务。为了实现这一点,你可以使用C++的多线程库,例如std::thread或boost::thread。首先,你需要在类中定义需要在不同线程中执行的函数或方法。然后,你可以创建一个线
c++中一个对象怎么运行多个线程
2024-02-29

怎么在java中使用ThreadPoolExecutor创建一个线程池

这篇文章给大家介绍怎么在java中使用ThreadPoolExecutor创建一个线程池,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发
2023-06-14

Python中怎么利用多线程创建一个程序

这篇文章给大家介绍Python中怎么利用多线程创建一个程序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Python线程创建需要关注threading.Thread.join(th) 或者th.join()如果你可以对
2023-06-17

c++中怎么实现一个对象运行多个线程

在C++中,可以使用线程库来实现一个对象运行多个线程。下面是一个简单的示例:#include #include class MyObject {public:void threadFunc(int id) {for(int i = 0
2023-10-25

怎么在java中实现一个多线程爬虫

怎么在java中实现一个多线程爬虫?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android
2023-06-14

C++中怎么实现一个多线程计数器

C++中怎么实现一个多线程计数器,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。以计数器实现为例子,演示了多线程计数器的实现技术方法,代码如下://目的: 测试利
2023-06-17

怎么在Android中实现一个多线程下载功能

怎么在Android中实现一个多线程下载功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、布局 界面上自上而下放置一个TextView,用来提示文本框中输
2023-05-30

自建云服务器要多少钱一个小时呢怎么设置

硬件成本购买一台服务器需要购买相关的硬件设备,包括CPU、内存、硬盘等。在购买服务器之前,需要了解自己的业务需求,确定需要多大的硬件配置。不同的云服务器提供商可能会提供不同的硬件配置选项,但大致相似。网络连接成本选择自建云服务器需要考虑所需的网络连接质量。一般来说,公共云服务提供商(如AWS、Azure等)提供高质量的
自建云服务器要多少钱一个小时呢怎么设置
2023-10-28

怎么在Andriod使用多线程实现一个轮播图功能

这篇文章将为大家详细讲解有关怎么在Andriod使用多线程实现一个轮播图功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。MainActivity了初始化控件。
2023-05-30

怎么在Android应用中实现一个HTTP多线程下载功能

本篇文章为大家展示了怎么在Android应用中实现一个HTTP多线程下载功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。多线程断点需要的功能1.多线程下载,2.支持断点。使用多线程的好处:使用多线
2023-05-31

怎么在Android中实现一个多线程断点续传下载功能

本篇文章给大家分享的是有关怎么在Android中实现一个多线程断点续传下载功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、布局实现具体布局内容如下:
2023-05-30

怎么在Android中利用多线程实现一个断点续传下载功能

怎么在Android中利用多线程实现一个断点续传下载功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。原理其实断点续传的原理很简单,从字面上理解,所谓断点续传就是从停止的地方重
2023-05-31

编程热搜

目录