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

时间:2015-02-26 18:59:07

标签: java multithreading data-distribution-service

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

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

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

4 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:1)

您使用的是什么DDS实现?如果您使用的DDS实现是在本机代码中实现的,这是非常典型的,那么DDS库创建的后台线程是本机线程,您将无法使Java调用像" setDaemon()& #34;他们......

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

了Gerardo

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

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

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