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

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

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

  • 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. make distclean

    清空bin目录make dirclean 清空所有相关的东西,包括下载的软件包,配置文件,feeds内容等make distclean 这个命令会删除feeds目录及其下面的所有的文件,直接结果就是运 ...

  2. centos memcached

    2014年1月19日 16:58:37 memcached 是基于libevent事件监听功能的,所以要安装 libevent 和 libevent-devel 启动命令 ./memcached -d ...

  3. PGP工作原理及其安全体制

    现代信息社会里,当电子邮件广受欢迎的同时,其安全性问题也很突出.实际上,电子邮件的传递过程是邮件在网络上反复复制的过程,其网络传输路径不确定,很容易遭到不明身份者的窃取.篡改.冒用甚至恶意破坏,给收发 ...

  4. (转)javascript方法--bind()

    地址:https://www.cnblogs.com/xxxxBW/p/4914567.html bind方法,顾名思义,就是绑定的意思,到底是怎么绑定然后怎么用呢,下面就来说说我对这个方法的理解. ...

  5. 用原生js实现ajax、jsonp

    转载: http://www.cnblogs.com/yangheng/p/6065910.html 一.原生js实现ajax $.ajax({ url: '', type: 'post', data ...

  6. Smooth Face Tracking with OpenCV

    先马克下,回头跑试试:http://synaptitude.me/blog/smooth-face-tracking-using-opencv/ GitHub:https://github.com/S ...

  7. 使用jstl方式替换服务器请求地址

    <c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>

  8. .NetCore下B/S结构 初探基于遗传学算法的中学自动排课走班(二)

    分析下染色体基因 这里用 老师 课程 班级 教室 周天 上下晚 课时作为染色体编码我封装了如下类 /// <summary> /// NP 授课事件 由教室.课程.班级 时间片段构成 li ...

  9. 微信隐藏的webJS Api汇总

    1.右侧菜单增加"查看公众账号" API document.getElementById('post-user').addEventListener('click', functi ...

  10. 修改Linux的基本配置

    1.修改主机名 vi /etc/sysconfig/network 2.修改ip地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0 ONBOOT=yes   ...