java - 阻止 Java 应用程序退出,直到 ThreadPool 为空

标签 java concurrency

我有一个 ExecutorService 位于一个单例类中,它接收来自许多不同类的任务。在应用程序关闭时,我需要等待池为空,然后才能允许应用程序退出。

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();
}

此代码包含在一个库中,该库将包含在另一个应用程序中,因此没有主方法可以让我等到池为空,除非我强制使用它的人这样做,但这不太好。

阻止应用程序终止(一段合理的时间)直到池为空的正确方法是什么?

最佳答案

您可以使用addShutdownHook捕获进程终止事件并在那里等待池。

示例:

 Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        NotificationService service = getInstance();
        service.executorService.shutdown();
        service.executorService.awaitTermination(30, TimeUnit.SECONDS);
      }
    });

关于java - 阻止 Java 应用程序退出,直到 ThreadPool 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40283221/

相关文章:

java - 在一个类中编辑变量似乎不会在另一个类中更改它

Java Servlet请求的并发问题

ios - 核心数据中的并发

.net - 当 ThreadPool.QueueUserWorkItem 返回 false

Scala:您知道任何高级 Actors 文档/教程吗?

java - 无法删除带有图像的目录

java - 在 Eclipse 的包资源管理器中突出显示类文件

java - LWJGL 只旋转一个物体

c# - ConcurrentBag 的预期用途和空作为终止条件

java - 使用 Java 删除 XML 字段中的空格