我有一个ExecutorService
坐在一个singleton类中,它接收来自许多不同类的任务。在应用程序关闭时,我需要等待池被清空,然后才允许应用程序退出。阻止Java应用程序退出,直到ThreadPool为空
private static NotificationService instance = null;
private ExecutorService executorService = Executors.newFixedThreadPool(25);
public static synchronized NotificationService getInstance() {
if (instance == null) {
instance = new NotificationService(true);
}
return instance;
}
在使用本NotificationService
,它经常发生,我重新启动应用程序和executorService
还没有处理完所有的通知。
对于测试,我可以手动关闭executorService并等待所有任务完成。
public static boolean canExit() throws InterruptedException {
NotificationService service = getInstance();
service.executorService.shutdown();
service.executorService.awaitTermination(30, TimeUnit.SECONDS);
return service.executorService.isTerminated();
}
覆盖finalize
方法并等待直到池为空是否可靠和安全?从我读过的内容来看,并不总是调用finalize,尤其是在使用单例类时。
@Override
protected void finalize() throws Throwable {
while (!canExit()){
Thread.sleep(100);
}
super.finalize();
}
此代码包含在将包含在另一个应用程序库,所以没有主要的方法,我可以等到池是空的,除非我用它这样做是不强迫人大。
什么是正确的方式来拖延应用程序(一段合理的时间)从终止,直到池是空的?
你的实现有什么问题? canExit()会阻止,直到执行器完成或30秒。把它放在一个循环中,直到它返回true,你应该没问题。 – Fildor
其他问题:实际处理所有通知至关重要吗?或者你能否比你能够更快地“取消”它们? - 当然,给定一个关机场景。 – Fildor
@Fidor,当我控制一切时,canExit可以工作,如前所述,这将用于库中,因此技术上我可以从shutdownhook调用canExit。在关机时,我至少有机会备份尚未发送的通知,所以即使很可能只有一个或两个未处理的项目在池中,我也不会丢失它们过程,那就是我以前的做法,当有人关闭Tomcat时处理最后一个或两个通知。 –