美文网首页
线程池的线程数怎么确定

线程池的线程数怎么确定

作者: 林_fbb8 | 来源:发表于2021-03-12 08:52 被阅读0次
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
    ......
}

有两个重要的参数设置:核心线程数corePoolSize,最大线程数maximumPoolSize。


6401.png

线程和哪些因素有关?

  1. CPU
    在最开始介绍多线程《多线程的由浅及深》时,介绍到线程共享进程的上下文环境,为更细粒度的CPU时间段。所以线程数的确定和CPU有关。至于CPU的核数和线程数的关系,可以查看这篇文章:CPU的核心数、线程数的关系和区别。(多线程实际上是计算机多种资源的并行运用,跟CPU有几个核心是没什么关系的)

  2. IO
    IO分为磁盘IO和网络IO。影响磁盘的关键因数是磁盘服务时间,即磁盘完成一个I/O请求所花费的时间,它由寻道时间、旋转延迟和数据传输时间三部分构成。衡量其关键指标,大致是IOPS、吞吐量等。影响网络IO的关键因素是服务器响应延时 + 带宽限制 + 网络延时 + 跳转路由延时 + 本地接收延时。

  3. 并行
    多个cpu实例或者多台机器同时执行一段处理逻辑

  4. 并发
    CPU不断切换线程来实现多路复用,以提升效率。通过cpu调度算法,看上去同时执行,实际上从cpu操作层面不是真正的同时。通常会用TPS或者QPS。

任务的性质

  1. CPU密集型任务
    要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。

    一般配置线程数=CPU总核心数+1 (+1是为了利用等待空闲)

  2. IO密集型任务
    这类任务的CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。常见的大部分任务都是IO密集型任务,比如Web应用。对于IO密集型任务,任务越多,CPU效率越高(但也有限度)。

    一般配置线程数=CPU总核心数 * 2 +1

总结

根据并发编程网的《如何合理地估算线程池大小》一文中的提示,

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

所以线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程

问题

  1. 是否使用线程池就一定比单线程效率高呢?

    否。比如Redis(点击查看)。

  2. 并发编程网的一个问题:

    2.1 高并发、任务执行时间短的业务怎样使用线程池?

    线程池线程数可以设置为CPU核数+1,减少线程上下文的切换

    2.2 并发不高、任务执行时间长的业务怎样使用线程池?

     a)假如是业务时间长集中在IO操作上,也就是IO密集型的任务,因为IO操作并不占用CPU,所以不要让所有的CPU闲下来,可以适当加大线程池中的线程数目,让CPU处理更多的业务         
     b)假如是业务时间长集中在计算操作上,也就是计算密集型任务,线程池中的线程数设置得少一些,减少线程上下文的切换 
    

    2.3 并发高、业务执行时间长的业务怎样使用线程池?

    并发高、业务执行时间长,解决这种类型任务的关键不在于线程池而在于整体架构的设计,看看这些业务里面某些数据是否能做缓存是第一步,增加服务器是第二步,以及线程池的设置。最后,业务执行时间长的问题,也可能需要分析一下,看看能不能使用中间件对任务进行拆分和解耦。

相关文章

  • 线程池的线程数怎么确定

    有两个重要的参数设置:核心线程数corePoolSize,最大线程数maximumPoolSize。 线程和哪些因...

  • ThreadPoolExecutor七大构造参数详解

    corePoolSize:线程池核心线程数(平时保留的线程数) maximumPoolSize:线程池最大线程数(...

  • 实现根据key分片的线程池-ShardThreadPoolExe

    实现一个线程池,该线程池可根据key来确定让哪一个线程来执行。该线程池是固定大小的线程池,初始化后不可改变线程的数...

  • 线程池原理

    线程池关键参数 核心线程数corePoolSize:线程池维护线程最少数量最大线程数 maxPollSize:线程...

  • java并发--普通线程池ThreadPoolTaskExecu

    1、普通线程池 普通线程池的重要概念: 1、核心线程数(CoreSize): 2、最大线程数(MaxSize): ...

  • ThreadPool

    线程池核心参数 corePoolSize: int 核心线程数 线程池初始化后,线程池中没有任何线程,线程池会等待...

  • juc9-Executors

    0 线程池类图 一 ForkJoinPool 分治线程池 二 ThreadPoolExecutor 固定线程数线程...

  • 八、线程池剖析

    一、前置问题 线程的状态转换 为什么要使用线程池 线程池的继承体系 线程池使用的场景 线程数的设置规则 线程池的状...

  • Android 中的线程池

    线程池核心参数 核心线程数 corePoolSize线程数容量 maximumPoolSize非核心线程被回收...

  • 线程池执行顺序

    线程池参数 corePoolSize 核心线程数, 最大线程数 maximumPoolSize, 线程没有执行任务...

网友评论

      本文标题:线程池的线程数怎么确定

      本文链接:https://www.haomeiwen.com/subject/oihnxhtx.html