为什么线程池执行完任务不会自动关闭?

想搞清楚这个问题,需要先看线程池原理:👉线程池原理

原因是,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,如果池中已有线程数超过核心线程数,那么timedtrue,三元表达式执行workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS),这个方法在规定时间内取不到任务就返回null,然后线程池会回收这个非核心线程。最后池中只剩下核心线程数了,也就是timed会变为false,那么三元表达式执行workQueue.take(),这个方法会一直阻塞,因为这时候队列是空的,直到队列中有任务为止。所以该Worker线程一直在运行。

这也是为什么我们在 main 方法中执行完线程池代码,虚拟机不会退出。这是并发编程,主线程执行完了,子线程还在执行呢。

想让线程池能自动关闭,把allowCoreThreadTimeOut设置为true就好了。

posted @ 2023-06-30 15:01  xfcoding  阅读(257)  评论(0编辑  收藏  举报