为什么线程池执行完任务不会自动关闭?
想搞清楚这个问题,需要先看线程池原理:👉线程池原理
原因是,Worker
线程启动后,会不断轮询,从阻塞队列中取任务,因为取不到任务,一直阻塞,Worker
线程一直在运行。看代码:
private Runnable getTask() {
...
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; // wc 是已有线程数
...
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
...
}
allowCoreThreadTimeOut
默认为false
,如果池中已有线程数超过核心线程数,那么timed
为true
,三元表达式执行workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)
,这个方法在规定时间内取不到任务就返回null
,然后线程池会回收这个非核心线程。最后池中只剩下核心线程数了,也就是timed
会变为false
,那么三元表达式执行workQueue.take()
,这个方法会一直阻塞,因为这时候队列是空的,直到队列中有任务为止。所以该Worker
线程一直在运行。
这也是为什么我们在 main 方法中执行完线程池代码,虚拟机不会退出。这是并发编程,主线程执行完了,子线程还在执行呢。
想让线程池能自动关闭,把allowCoreThreadTimeOut
设置为true
就好了。