线程池的corePoolSize大小为什么设置为N+1或2N?
根据业务场景来设置线程池中的各个参数。
分析线程池处理的任务是CPU密集型还是IO密集型:
- CPU密集型:corePoolSize = N + 1
- IO密集型:corePoolSize = 2 * N
注意:N+1和2N都是经验值。
出发点:希望CPU一刻不停的工作。
为什么CPU密集型是N+1?
CPU密集型场景下,我们就不再考虑IO了。这时候CPU空闲的原因一般就是正在处理的任务出现错误,暂停了。这个时候如果我们有另一个任务恰好补上来,那CPU就没得歇了。所以是N+1。当然这也是经验值。
网上也有说法是,CPU密集型是N-2N。这个也不难理解,如果我们N个线程都在处理任务,他们发生了错误,每个都有个替补的不上,这就是2N了。
为什么IO密集型是2N?
理想线程数=最大并行数*(CPU计算时间+等待时间)/CPU计算时间
如果理想的认为CPU计算时间等于CPU等待时间,那么理想线程数就是2N了。
当然大部分场景下这是不可能的。一般Web项目中IO时间(CPU等待时间)都远高于CPU计算时间(因此MySQL才会用B+树做索引来减小每查找一层增加的IO)。比如一个简单的数据库查询,CPU计算时间可能只有0.1ms,CPU的IO时间则可能达到2ms,这样一算,就是21N了。所以说2N只是个理想的经验值,在高IO时间开销的场景,可以是10N、20N、30N等等。