1

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

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

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

4

4 回答 4

2

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

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

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

这应该回收参与者持有/创建的任何资源(包括线程)。

于 2015-02-28T15:26:52.397 回答
1

你使用的是什么 DDS 实现?如果您使用的 DDS 实现是在本机代码中实现的,这是非常典型的,那么 DDS 库创建的后台线程是本机线程,您将无法在它们上进行 Java 调用,例如“setDaemon()”。 ..

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

杰拉尔多

于 2015-03-02T06:36:37.423 回答
0

“优雅地关闭后台线程”将需要这些线程的合作,即它们必须提供某种 API 来请求关闭。

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

try {
    doSomethingThatMightThrowAnException();
} catch (Throwable t) {
    reportError(t);
    System.exit();
}
于 2015-02-26T23:07:12.297 回答
0

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

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

一旦最后一个非守护线程死亡,Java 虚拟机就会关闭并退出。当您的程序第一次启动时,main() 线程是唯一的非守护线程。

于 2015-02-26T22:51:49.050 回答