线程池线程数目的确定

在上一篇文章《java线程的创建(重点:线程池的使用,线程池不允许使用Executors创建)》中有关线程池的配置中,

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              RejectedExecutionHandler handler) {
    ......
}

       缓冲队列queue和异常处理策略handler已经说明,但还有两个重要的参数设置:核心线程数corePoolSize,最大线程数maximumPoolSize。所以线程数的确定也很重要,下面是我查阅资料和自己理解的结果

线程和哪些因素有关?

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

 

参考:

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

《如何合理设置线程池大小》

《IO与CPU跟线程的关系》

《廖雪峰:python进程vs线程》

 

你可能感兴趣的:(多线程)