【发布时间】:2012-01-06 20:55:56
【问题描述】:
我对在使用ExectuorService 调度的线程上有序关闭的想法感到满意;也就是说,调用shutdown或shutdownNow会导致池上创建的线程优雅退出。如果他们回复interrupt,您可以确定 finally etc 将被调用,您将获得一个干净、可预测的退出(您可以在其中清理任何资源等)。
但是,如果您已将线程设置为守护进程(通过执行程序的ThreadFactory),如下所示。
ExecutorService pool = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
在主线程终止后,VM 将突然终止所有守护线程。 在上面的例子中,一个被调度然后突然终止的(守护进程)线程将绕过任何 finally 块并且任何可中断的方法都不会抛出InterruptedException。
所以,我倾向于认为将ThreadPoolExecutor 的池中使用的线程标记为守护进程是不好的做法……我的问题实际上是关于帮助我说出为什么。
为什么在ExecutorService 的线程池中使用守护线程是不好的做法(或者如果您不同意)?特别是我有兴趣通过优雅关闭(具有中断策略并且运行良好的线程)与守护线程来描述 VM 关闭的生命周期。
扩展最后一点,ThreadPoolExecutor 上的finalize 将在其自身上调用shutdown,但是当它使用守护线程时,如果 VM 调用了finalize,它们可能已经终止。那么线程池的行为是什么?如果底层线程突然终止,它是否可以被欺骗以保持活动状态(因此不退出 VM)?
我问的部分原因是因为我已经看到它用来绕过关闭实际 ExectorService 的需要。你能想到绕过 its 关闭生命周期会产生不良影响的场景吗?到目前为止,我能想到的使用守护进程的唯一原因是走捷径,我想了解它可能导致的任何意想不到的副作用。
【问题讨论】:
标签: java multithreading concurrency daemon executorservice