直接创建大量线程的坏处

对于一个web服务器,服务器应用程序会处理来自客户端的请求。假设,每到达一个请求,我们的程序都为该请求创建一个线程来执行请求任务,那么这个创建的线程数目将会是无穷无尽的,“为每一个请求任务分配一个线程”,该做法是存在一些缺陷的,尤其是创建大量线程时:

(1)线程的生命周期的开销高:我们要明白线程的创建和销毁是需要代价的,如果说客户端请求的任务是很轻量级的,往往这种任务所执行的时间都很短并且做的事也很简单,那么为每一个请求创建线程,会消耗大量的计算机资源的。

(2)资源的消耗:一个活跃的线程会消耗系统的资源,特别是内存。当创建的线程太多时并且多过了CPU的核心数,必定会有线程会闲置。当大量线程闲置时,会占用大量的内存(极有可能会造成OOM异常),而且这么多的线程之间也会因为CPU的不足而存在竞争(线程经常得在用户态和内核态之间转换需要开销),所以当你的线程数如果达到了刚好使CPU处于忙碌,那么这时继续创建新线程,反而会降低性能。

线程池的作用

线程池作用就是限制系统中执行线程的数量。
       根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。

为什么要用线程池:

(1)减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

(2)可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

那么在创建线程池时,我们又该如何设置好线程池的大小呢?

首先,设置一个线程池之前,我们先要知道线程所执行的任务,都是有不同的执行策略的:

(1)依赖性任务:大多数的任务都是不依赖于其他任务所执行的时序、时长、执行结果,但是如果一个任务执行需要依赖于其他的任务,那么该任务可以被认为是有依赖性的。

(2)线程封闭的任务:该任务在执行时,其他任务都不能执行,适合单线程池。

(3)响应时间敏感的任务:在上面的线程封闭任务,如果一个执行时间很长的任务交给单线程池去做,那么很长时间才会得到反馈,,所以时间敏感的任务不适合单线程模式。

对于依赖性很强的任务,要时刻注意线程池里的线程数目不能过小,因为线程数如果不够,A任务所依赖的B任务可能就要被放入等待队列,那么此时A任务就很可能执行不下去,最极端的情况可能就是B此时正好需要A任务所占用的线程,这时就会导致“线程饥饿死锁”。

那么如何设置线程池大小?

性质不同的任务可以交给不同规模的线程池执行。

任务的性质:

(1)CPU密集型

(2)I/O密集型

(3)混合型任务

对于不同性质的任务来说,CPU密集型任务应配置尽可能小的线程,因为如果为CPU密集型的任务开启太多的线程,那么CPU为了调度好这些线程会消耗太多资源。而IO密集型任务应配置尽可能多的线程,因为IO操作不占用CPU,所以尽管线程比较多,CPU也不用为了调度线程而花费太多开销,所以可以加大线程数量(但是也别太多)。

若任务对其他系统资源有依赖,如某个任务依赖数据库的连接返回的结果,这时候等待的时间越长,则CPU空闲的时间越长,那么线程数量应设置得越大,这样CPU就会去处理其他的线程,所以才能更好的利用CPU。 
       当然具体合理线程池值大小,需要结合系统实际情况,在大量的尝试下比较才能得出,以上只是前人总结的规律。

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

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

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

总结: 
       线程等待时间所占比例越高(线程此时很可能在等待依赖性任务完成或者处于IO阻塞,此时不占CPU,所以应该创建更多的线程让空闲的CPU去处理),需要越多线程。线程CPU时间所占比例越高,需要越少线程。

高并发、任务执行时间短的业务怎样使用线程池?并发不高、任务执行时间长的业务怎样使用线程池?并发高、业务执行时间长的业务怎样使用线程池? 
(1)高并发、任务执行时间短的业务:因为时间短,很可能就是CPU密集型,所以线程不宜过多,和CPU核心数差不多就好。
(2)并发不高、任务执行时间长的业务要区分开看: 
  a)假如是业务时间长集中在IO操作上,也就是IO密集型的任务,因为IO操作并不占用CPU,所以不要让所有的CPU闲下来,可以适当加大线程池中的线程数目,让CPU处理更多的业务 。
  b)假如是业务时间长集中在计算操作上,也就是计算密集型任务,这个就没办法了,和(1)一样吧,线程池中的线程数设置得少一些,减少线程上下文的切换 。
(3)并发高、任务执行时间又长,解决这种类型任务的关键不在于线程池而在于整体架构的设计,看看这些业务里面某些数据是否能做缓存是第一步,增加服务器是第二步,至于线程池的设置,设置参考(2)。最后,业务执行时间长的问题,也可能需要分析一下,看看能不能使用中间件对任务进行拆分和解耦。

转载于:https://www.cnblogs.com/Booker808-java/p/9532227.html

线程池----合理的设置大小相关推荐

  1. java线程池的参数设置

    java线程池的参数设置 在说如何对线程池优化之前重复一下线程的7大参数 corePoolSize: 核心线程数,也是线程池中常驻的线程数,线程池初始化时默认是没有线程的,当任务来临时才开始创建线程去 ...

  2. 线程池参数如何设置?

    前言 着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供的线程池:ThreadPoolExecutor类,帮助开发 ...

  3. 线程池到底参数设置多少线程才合适?

    目录 一.抛出问题 二.分析 三.实际应用 四.总结: 抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 「第一派:<Java Con ...

  4. python3 ThreadPoolExecutor 线程池大小设置

    线程池的理想大小取决于被提交任务的类型以及所部署系统的特性.线程池应该避免设置的过大或过小,如果线程池过大,大量的线程将在相对很少的CPU和内存资源上发生竞争,这不仅会导致更高的内存使用量,而且还可能 ...

  5. 从原理上搞懂如何设置线程池参数大小?

    我们在使用线程池的时候,会有两个疑问点: 线程池的线程数量设置过多会导致线程竞争激烈 如果线程数量设置过少的话,还会导致系统无法充分利用计算机资源 那么如何设置才不会影响系统性能呢? 其实线程池的设置 ...

  6. matlab 设置最大并行数_浅析线程池参数设置

    背景 首先先明确一下线程池的主要作用是什么 线程池解决的核心问题就是资源管理问题.在并发环境下,系统不能够确定在任意时刻中,有多少任务需要执行,有多少资源需要投入.这种不确定性将带来以下若干问题: 频 ...

  7. 线程池的创建及参数设置详解

    一. 常见线程池 线程池的创建方法主要有两类,第一是通过Executors 创建线程池,第二是通过 ThreadPoolExecutor 创建线程池. 首先我们来看通过Executors 创建的线程池 ...

  8. 面试必问---Java线程池8大拒绝策略

    前言 谈到java的线程池最熟悉的莫过于ExecutorService接口了,jdk1.5新增的java.util.concurrent包下的这个api,大大的简化了多线程代码的开发.而不论你用Fix ...

  9. 深入理解Java线程池:ThreadPoolExecutor

    线程池介绍 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题: 如果并发的请求数量非常多,但每个线 ...

最新文章

  1. 图书借阅系统java_基于JAVAWEB的图书借阅系统
  2. Eclipse,NetBeans及IntelliJ—Java IDE大战之NetBeans篇
  3. 1.2 Java系统流
  4. 计算机网络 实验教案,《计算机网络》实验教案.pdf
  5. 重磅!阿里云发布业界首款SaaS化防火墙
  6. 学pyqt5之前需要学python吗_快速学习pyqt5(1)--入门
  7. Qt OpenGL 图像的平移(使用glTranslatef)
  8. Objectove-c单例模式
  9. 蓝桥杯 ALGO-124 算法训练 数字三角形
  10. spark 读取elasticsearch数据
  11. 德江多措施推进大数据应用“智慧德江”建设
  12. video上传架构设计与实现
  13. Android 多媒体开发学习之简单的音乐播放器
  14. 天翼对讲机写频软件_【对讲机的那点事】摩托罗拉GM950E/I 车载台如何编程?(上)...
  15. 我们应能在哪个层次使用计算机,福师20秋《计算机应用基础》在线作业一题目【标准答案】...
  16. 自适应函数符和函数适配器(Adaptable Functors and Function Adapters)
  17. valgrnd调试详解
  18. C语言结构体字节对齐规则
  19. excel使用教程_数据分析Excel必备技能:数据透视表使用教程
  20. 最佳机器学习公共数据集

热门文章

  1. 《Python入门到精通》Python基础语法
  2. OSI网络模型(TCP/IP五层模型)
  3. mariadb忘记密码修改密码
  4. [Springboot]SpringCache + Redis实现数据缓存
  5. 解决jfinal-ext CsvRender 中文乱码
  6. java新手的第一个小东西,或许小东西都算不上=。 =
  7. STL札记2(序列容器vector、list、deque)
  8. 如何查看sql2005数据库的端口号
  9. .NET网络编程学习(一)
  10. JAVA在线编译,无需环境变量