ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java线程池核心线程用尽后为何优先排队而不是继续创建线程直至最大线程数? [打印本页]

作者: 兜兜零元    时间: 2024-5-19 00:07
标题: Java线程池核心线程用尽后为何优先排队而不是继续创建线程直至最大线程数?
前阵子在v2ex上看到这篇帖子讨论这个标题,有意思的是这个如此基础的标题在Javaer的天下里并没有广泛的共识,下面的答复也是七嘴八舌的,刚幸亏《Java Performace》上看到对这个标题的解释,实验总结一下。
原因

书中对线程池的解释基于以下几点前提:
理想情况下线程池中Runnable的线程数应该刚好等于CPU核心数,如果任务都是CPU密集型,那么线程数就等于核心数;如果是IO密集型,那么就需要计算CPU耗时和IO耗时的比例来调解核心线程数。实际中的情况往往更加复杂,任务可能有CPU密集的也有IO密集的,IO密集的耗时比例也不尽雷同。调解核心线程数、最大线程数和队列长度来获得理想的体系吞吐和请求耗时这是开发者的责任,线程池提供机制但无法办理这个标题。
线程池的逻辑或者说约定:
如上,可见设置的关键是核心线程数,核心线程数应该尽量使CPU饱和(或者达到我们期望的负载)但又不会产生过多的上下文切换。思量到任务的复杂性,这个参数确实只能通过压力测试来得到。
其它的一些模式

ThreadPoolExecutor的配置是非常灵活的,可能通过调解参数使得线程池接纳一些别的行为。
令核心线程数等于最大线程数,就可以取得原贴所期望的,可能也是大部门人所期望的,到达最大线程数后再排队。不过核心线程是不会被回收的,如果确实需要回收可以设置allowCoreThreadTimeOut。如果使用无容量限制的队列如 LinkedBlockedingQueue那么行为就和Executors#newFixedThreadPool雷同。
令队列长度等于0,最大线程数等于无限(Integer#MAX_VALUE,等效于无限),此时所有任务都会直接提交给线程,没有空闲的就新建,不会有任务排队。此时等效于Executors#newCachedThreadPool。
上面两种方式多多少少都有点标题,这也是为什么不建议通过Executors来创建线程池。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4