Daemon线程调度在ExecutorService上;解释为什么这是坏的形式 [英] Daemon threads scheduled on an ExecutorService; explain why this is bad form

查看:1522
本文介绍了Daemon线程调度在ExecutorService上;解释为什么这是坏的形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很满意在使用 ExectuorService 计划的线程上有序关闭的想法;也就是说,调用 shutdown shutdownNow 将导致在池上创建的线程正常退出。如果他们响应 interrupt ,你可以确定finally等将被调用,你会得到一个干净,可预测的退出(你可以清理任何资源等)。

I'm comfortable with the idea of orderly shutdown on threads scheduled with an ExectuorService; that is to say, calling shutdown or shutdownNow will cause threads created on the pool to exit gracefully. If they respond to interrupt you can be sure finally etc will be called and you'll get a clean, predictable exit (where you can cleanup any resources etc).

但是,如果你已经将线程设置为一个守护进程(通过执行器的 ThreadFactory )如下。

However, if you've set your thread to be a daemon (via the executor's ThreadFactory) as below.

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

after the main thread terminates, the VM will abruptly terminate any daemon threads. In the example above, a (daemon) thread scheduled and then abruptly terminated will bypass any finally blocks and any interruptable methods won't throw InterruptedException.

所以,我倾向于认为将 ThreadPoolExecutor 的池中使用的线程标记为守护进程是不好的做法...

So, I tend to think that marking the threads used in a ThreadPoolExecutor's pool as daemon is bad practice... my question is really about helping me vocalise why.

为什么是不好的做法(如果你不同意的话)在 ExecutorService 的线程池中使用守护线程?特别是我有兴趣描述虚拟机关机的生命周期与正常关闭(线程,有中断策略和运行良好)vs守护线程。

Why is it bad practice (or not if you disagree) to use daemon threads in a ExecutorService's thread pool? In particular I'm interested in describing the life-cycle of the VM shutdown with graceful shutdown (threads that have an interruption policy and play nicely) vs daemon threads.

扩展最后一个点, finalize ThreadPoolExecutor 将调用 shutdown 本身,但是当它使用守护线程时,如果 finalize 被VM调用,它们可能已经终止。线程池的行为是什么?如果底层线程突然终止,它可以被诱骗为剩余活动(因此不退出VM)?

Expanding that last point, finalize on ThreadPoolExecutor will call shutdown on itself, but when it's using daemon threads, they could have terminated already if finalize was called by the VM. What's the behavior of the thread pool then? Can it be tricked into remaining alive (and so not exiting the VM) if underlying threads terminated abruptly?

我要求的部分原因是因为我已经看到它用于绕过需要关闭实际的ExectorService。你能想到绕过其关机生命周期的情况会有不良影响吗?到目前为止,我可以想出的使用守护进程的唯一原因是采取一个捷径,我想欣赏任何意外的影响,它可能导致。

Part of the reason I'm asking is because i've seen it used to bypass the need to shutdown the actual ExectorService. Can you think of scenarios where bypassing its shutdown life-cycle can have ill affect? So far, the only reason I can come up with for using daemons is to take a short cut and I want to appreciate any unexpected side affects it could cause.

推荐答案


在ExecutorService的线程池中使用守护线程是不好的做法吗?

is it bad practice to use daemon threads in a ExecutorService's thread pool?

如果发送到该特定 ExecutorService 的任务可以突然终止,那么为什么不是,这是守护进程线程做的。但一般来说,没有很多任务可以被终止,没有关闭仪式,所以如果你选择守护线程,你必须知道你在做什么。

If the tasks sent to that particular ExecutorService are ok to be terminated abruptly, then why not, that's what daemon threads do. But generally, there are not many tasks that are ok to be terminated with no shutdown ceremonies at all, so you must know what you're doing if you opt to daemon threads.

finalize() 。有没有保证什么时候,任何特定的对象将是GCd, ThreadPoolExecutor 也不例外,因此它的 finalize()可以调用也可以不调用。该行为取决于特定的JRE实现,即使具有相同的实现,也可能不时变化。

finalize() is called when an object is about to be garbage collected. There are no guarantees on when, if ever, any particular object will be GCd, and ThreadPoolExecutor is no exception, so its finalize() may or may not be called. The behavior depends on the particular JRE implementation, and even with the same implementation, may vary from time to time.

这篇关于Daemon线程调度在ExecutorService上;解释为什么这是坏的形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆