我对使用ExecutorService
调度的线程进行有序关闭的概念感到舒适; 也就是说,调用shutdown
或shutdownNow
将导致在池中创建的线程优雅地退出。如果它们响应interrupt
,您可以确保会调用finally等,并且您将获得干净且可预测的退出(可以清理任何资源等)。
但是,如果您已将线程设置为守护程序(通过执行器的ThreadFactory
),如下所示:
ExecutorService pool = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
在主线程终止后,虚拟机会突然终止任何守护线程。在上面的示例中,调度然后突然终止的(守护)线程将绕过任何finally块,并且任何可中断方法都不会抛出InterruptedException
。
因此,我倾向于认为将ThreadPoolExecutor
池中使用的线程标记为守护线程是一个不好的做法... 我的问题实际上是帮助我表述为什么。
在ExecutorService
线程池中使用守护线程为什么是不好的做法(如果您不同意则不是)?特别地,我对描述具有优雅关闭(具有中断策略并且表现良好的线程)的 VM 关闭的生命周期,与守护线程相比,很感兴趣。
扩展上述最后一点,ThreadPoolExecutor
上的finalize
将在其自身上调用shutdown
,但是当它使用守护线程时,如果VM调用了finalize
,它们可能已经终止。那么线程池的行为是什么?如果基础线程突然终止,它能被欺骗为保持活动状态(从而不退出VM)吗?
我提出这个问题的部分原因是因为我曾看到它用于绕过需要关闭实际ExectorService
的需求。您能想到绕过其关闭生命周期可能会产生不良影响的情况吗?到目前为止,我能想到使用守护线程的唯一原因是为了节省时间,我想知道它可能会引起的任何意外副作用。