目录
一、理论分析
二、实际应用
为了加快程序处理速度,我们会将问题分解成若干个并发执行的任务。并且创建线程池,将任务委派给线程池中的线程,以便使它们可以并发地执行。在高并发的情况下采用线程池,可以有效降低线程创建释放的时间花销及资源开销,如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及“过度切换”(在JVM中采用的处理机制为时间片轮转,减少了线程间的相互切换) 。
但是有一个很大的问题摆在我们面前,即我们希望尽可能多地创建任务,但由于资源所限我们又不能创建过多的线程。那么在高并发的情况下,我们怎么选择最优的线程数量呢?选择原则又是什么呢?
一、理论分析
关于如何计算并发线程数,有两种说法。
第一种,《Java Concurrency in Practice》即《java并发编程实践》8.2节 170页
对于计算密集型的任务,一个有Ncpu个处理器的系统通常通过使用一个Ncpu+ 1个线程的线程池来获得最优的利用率(计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作)。对于包含了 I/O和其他阻塞操作的任务,不是所有的线程都会在所有的时间被调度,因此你需要一个更大的池。为了正确地设置线程池的长度,你必须估算出任务花在等待的时间与用来计算的时间的比率;这个估算值不必十分精确,而且可以通过一些监控工具获得。你还可以选择另一种方法来调节线程池的大小,在一个基准负载下,使用 几种不同大小的线程池运行你的应用程序,并观察CPU利用率的水平。
给定下列定义:
Ncpu