主线程抛出异常时停止后台线程

Stop background thread when exception is thrown in main thread

我正在 Java 中编写一个程序,该程序使用 DDS 消息传递机制,在创建编写器等时启动自己的后台 threads。但是,如果在 main thread 中发生错误,我将使用以下代码抛出 exception

throw new FooUncheckedException(writerTypes.get(i) + " is not a writer type");

主线程然后像预期的那样终止。但是,由我正在使用的 DDS 库创建的 后台线程 继续 运行 因此程序在技术上永远不会停止 运行ning。我将如何优雅地关闭 后台线程 以及使程序保持活动状态?

如果您在启动后台线程之前设置后台线程的守护进程标志,那么当您的主线程退出时它们将被自动杀死。

Thread t = new Thread(...);
t.setDaemon(true);
t.start();

A Java 虚拟机将在最后一个非守护线程死亡后立即关闭并退出。当您的程序首次启动时,main() 线程是唯一的非守护线程。

"gracefully shutting down the background threads" 将需要这些线程的合作,即它们必须提供某种 API 来请求关闭。

如果可以立即杀死这些线程(不给他们机会完成当前正在做的事情),并且你想终止整个程序的执行,System.exit()可能是最好的选择.如果您想在发生未处理的异常时执行此操作,您可以在 main 方法中捕获异常:

try {
    doSomethingThatMightThrowAnException();
} catch (Throwable t) {
    reportError(t);
    System.exit();
}

在退出主线程之前,我会尝试这样清理:

participant.delete_contained_entities(); 
DomainParticipantFactory.get_instance().delete_participant(participant);

[为您可能创建的每个参与者重复...]

这应该回收参与者的任何资源(包括线程)held/created。

您使用的是哪种 DDS 实现?如果您使用的 DDS 实现是在本机代码中实现的,这很典型,那么 DDS 库创建的后台线程就是本机线程,您将无法进行 Java 调用 "setDaemon()" 在他们身上...

上面 C Tucker 描述的机制是标准 DDS API 释放 DDS 中间件库为给定 DomainParticipant 创建的所有资源,因此除其他外,这应该终止 DDS 实现的任何内部线程开始了。如果它没有这样做,我会认为是该特定 DDS 实现中的错误。

杰拉尔多