eads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
* 如果为false(默认值),核心线程即使在空闲时也会保持活动状态。
* 如果为true,核心线程将使用keepAliveTime超时等待工作
*/
private volatile boolean allowCoreThreadTimeOut;
综上所述,因此线程池需要构建空任务的非核心线程去处理这种情况。
线程池使用完为什么必须执行shutdown方法或者shutdownNow方法?
- 第一点:在线程池 addWorker 方法中我们可以看到,
线程池启动线程也是基于 Thread 对象去进行的一个 start 方法启动的,像这种它会占用jvm的栈,
所以属于GC Roots 通过垃圾回收的可达性分析算法,这种线程就不能被回收,会一直占用jvm的资源,
因此不能及时的调用 shutdown 或者 shutdownNow 方法,就可能造成内存泄漏问题!!!
- 第二点:线程池启动对象是基于你 Worker 对象内部的 Thread 对象启动的,
当执行Thread对象的 start方法时,它会执行 Worker对象的 run 方法,
该方法中的runWorker 方法传入的是 this 就是当前的Worker对象,
就会导致启动的线程还指向了Worker对象,这个Worker对象是不能回收的,
又因为Worker对象属于线程池的内部类,
导致整个 ThreadPoolExecutor 线程池对象也不会被回收!!!
综上所述,当使用完线程池对象后,没有及时的调用关闭方法,会导致堆内存资源消耗很严重,最后会导致内存泄漏问题!
线程池的核心参数该如何设置?
主要的难点在于任务类型无法控制,比如:
cpu密集型: cpu不断的处理任务,大量的计算等操作。
IO密集型: 不需要cpu一直调度,大多数时间都是等待结果的,如:调用第三方服务等待网络响应、等待IO响应、查询数据库等待数据库响应等等。
混合型:上面两种都会有。
大多数情况都需自己去测试,调试!没有绝对固定的一个公式。可以参考:
M thread = N cpu * U cpu * ( 1 + W / C )
线程数 = cpu的个数 * cpu的利用率 * ( 1 + 等待时间 / 计算时间 ) 注:W/C 是程序运行时 等待时间和计算时间的比值
1 * 100% * (1 + 50% / 50% )= 2
公式只是给定一个调试的初始值,需要自己后续测试调试!
以上可能还有不足,仅供参考!!!