线程池应该设置多少线程合适,怎么样估算出来。最近接触到一些相关资料,现作如下总结。

最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊。

首先,需要考虑到线程池所进行的工作的性质:

  • IO密集型
  • CPU密集型

简单的分析来看,如果是CPU密集型的任务,我们应该设置数目较小的线程数,比如CPU数目加1。如果是IO密集型的任务,则应该设置可能多的线程数,由于IO操作不占用CPU,所以,不能让CPU闲下来。当然,如果线程数目太多,那么线程切换所带来的开销又会对系统的响应时间带来影响。

《linux多线程服务器端编程》中有一个思路,CPU计算和IO的阻抗匹配原则。

如果线程池中的线程在执行任务时,密集计算所占的时间比重为P(0<P<=1),而系统一共有C个CPU,为了让CPU跑满而又不过载,线程池的大小经验公式 T = C / P。在此,T只是一个参考,考虑到P的估计并不是很准确,T的最佳估值可以上下浮动50%。

这个经验公式的原理很简单,T个线程,每个线程占用P的CPU时间,如果刚好占满C个CPU,那么必有 T * P = C。

下面验证一下边界条件的正确性:

假设C = 8,P = 1.0,线程池的任务完全是密集计算,那么T = 8。只要8个活动线程就能让8个CPU饱和,再多也没用了,因为CPU资源已经耗光了。

假设C = 8,P = 0.5,线程池的任务有一半是计算,有一半在等IO上,那么T = 16.考虑操作系统能灵活,合理调度sleeping/writing/running线程,那么大概16个“50%繁忙的线程”能让8个CPU忙个不停。启动更多的线程并不能提高吞吐量,反而因为增加上下文切换的开销而降低性能。

如果P < 0.2,这个公式就不适用了,T可以取一个固定值,比如 5*C。另外公式里的C不一定是CPU总数,可以是“分配给这项任务的CPU数目”,比如在8核机器上分出4个核来做一项任务,那么C=4

文章如何合理设置线程池大小里面提到了一个公式:

最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:

最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

可以得出一个结论:
线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。

workQueue:保存任务的阻塞队列,与线程池的大小有关:

  当运行的线程数少于corePoolSize时,在有新任务时直接创建新线程来执行任务而无需再进队列
  当运行的线程数等于或多于corePoolSize,在有新任务添加时则选加入队列,不直接创建线程
  当队列满时,在有新任务时就创建新线程

线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事的更多相关文章

  1. ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别

    工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍ThreadP ...

  2. hreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别

    阅读更多 工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍Th ...

  3. Java-如何合理的设置线程池大小

    想要合理配置线程池线程数的大小,需要分析任务的类型,任务类型不同,线程池大小配置也不同. 配置线程池的大小可根据以下几个维度进行分析来配置合理的线程数: 任务性质可分为:CPU密集型任务,IO密集型任 ...

  4. Java并发线程池到底设置多大?

    前言 在我们日常业务开发过程中,或多或少都会用到并发的功能.那么在用到并发功能的过程中,就肯定会碰到下面这个问题 并发线程池到底设置多大呢? 通常有点年纪的程序员或许都听说这样一个说法 (其中 N 代 ...

  5. 如何决定 Web 应用的线程池大小

    在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务.通常是通过 ...

  6. 如何决定Web应用的线程池大小

    线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...

  7. 用 ThreadPoolExecutor/ThreadPoolTaskExecutor 线程池技术提高系统吞吐量(附带线程池参数详解和使用注意事项)

    1.概述 在Java中,我们一般通过集成Thread类和实现Runnnable接口,调用线程的start()方法实现线程的启动.但如果并发的数量很多,而且每个线程都是执行很短的时间便结束了,那样频繁的 ...

  8. ThreadPoolExecutor线程池参数设置技巧

    一.ThreadPoolExecutor的重要参数   corePoolSize:核心线程数 核心线程会一直存活,及时没有任务需要执行 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线 ...

  9. 如何计算tomcat线程池大小?

    背景 在我们的日常开发中都涉及到使用tomcat做为服务器,但是我们该设置多大的线程池呢?以及根据什么原则来设计这个线程池呢? 接下来,我将介绍本人是怎么设计以及计算的. 目标 确定tomcat服务器 ...

随机推荐

  1. KVM -> 虚拟化简介&虚拟机安装_01

    什么是虚拟化? 在计算机技术中,虚拟化(技术)或虚拟技术(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源(CPU.内存.磁盘空间.网络适配器等),予以抽象.转换后呈现 ...

  2. TcxGrid 内容 行高度

  3. Python PIL: cannot write mode RGBA as BMP(把有四位通道(RGBA)的图片换成有三位通道的(RGA))

    图片png结尾的有四个通道RGBA,把四个通道改为三个通道(RGB),如下,bg为修改后的图片 img = Image.open('pic\\find.png')bg = Image.new(&quo ...

  4. IdentityServer4结合AspNetCore.Identity实现登录认证踩坑填坑记录

    也可以自定义实现,不使用IdentityServer4.AspNetIdentity这个包,当然还要实现其他接口IResourceOwnerPasswordValidator. IProfileSer ...

  5. Linux系统运维笔记(四),CentOS 6.4安装 MongoDB

    Linux系统运维笔记(四),CentOS 6.4安装 MongoDB 1,下载 https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6 ...

  6. 【PAT】1060 Are They Equal (25)(25 分)

    1060 Are They Equal (25)(25 分) If a machine can save only 3 significant digits, the float numbers 12 ...

  7. sonarQube代码管理工具

    第一步:安装环境:jdk 1.8   idea  mysql5.6以上  sonarqube5.6.6 第二歩:下载好sonarqube后,解压打开bin目录,启动相应OS目录下的StartSonar ...

  8. HTML5 LocalStorage 本地存储(转)

    原文:http://www.cnblogs.com/xiaowei0705/archive/2011/04/19/2021372.html HTML5 LocalStorage 本地存储 说到本地存储 ...

  9. 006.FTP用户访问控制配置

    一 FTP控制文件 1.1 文件说明 /etc/vsftpd/ftpusers:黑名单,优先级高 #通常不修改此文件 /etc/vsftpd/user_list:黑名单,优先级相对低 注意:Linux ...

  10. 循序渐进学.Net Core Web Api开发系列【11】:依赖注入

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍如 ...