在ExecutorService的线程池中使用守护程序线程是不好的做法吗?
如果任务发送到那个特定的 ExecutorService 可以突然终止,那么为什么不,这就是守护程序线程所做的。但通常情况下,没有很多任务可以在没有关闭仪式的情况下终止,因此如果您选择守护程序线程,您必须知道自己在做什么。
ExecutorService
finalize() 在对象出现时调用 即将被垃圾收集 。如果有的话,任何特定的对象都将成为GCd,并不能保证 ThreadPoolExecutor 也不例外,所以它 finalize() 可能会也可能不会被召唤。行为取决于特定的JRE实现,即使具有相同的实现,也可能随时变化。
finalize()
ThreadPoolExecutor
我倾向于为守护进程和非守护进程线程使用不同的池。守护进程池往往会执行重复清理作业,监视和后台任务,如果一个或两个未执行则无关紧要。任何只在应用程序仍在运行时才有意义的任务都可以创建一个守护程序线程任务。例如GC线程是守护程序线程。
守护程序线程可能很有用,如果它们没有突然终止,它们就不会那么有用IMO。
据推测,我们可以设想另一种类型的线程,当没有正常的线程运行时它会被中断,而不是突然终止。这可能有点方便,但如果你不得不做任何清理工作,那么你很可能想要有条不紊地进行清理。这将限制此功能的便利性。
另一方面,如果你有任务在关机时不需要任何清理,那么deamon线程非常方便。并且你不想浪费时间等待它们到达某个特定状态或冒着停机等问题,因为你使用deamon线程的原因是因为你不需要任何清理。如果应用程序执行任何操作将是浪费时间。正在关闭。如果你关心,那么你不应该使用deamon线程。
与deamon线程池没什么不同。如果该线程池正在执行在关闭时不需要任何清理的任务,那么由于方便起见,这将是有意义的。
来自 JCiP书 :
应该谨慎使用守护程序线程,可以在没有清理的情况下随时安全地放弃处理活动。特别是,将守护程序线程用于可能执行任何类型I / O的任务是危险的。守护程序线程最好保存用于“内务”任务,例如后台线程定期从内存缓存中删除过期的条目