【问题标题】:Stop background thread when exception is thrown in main thread主线程抛出异常时停止后台线程
【发布时间】:2015-02-26 18:59:06
【问题描述】:

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

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

主线程然后按预期终止。但是,我使用的DDS 库创建的后台线程 会继续运行,因此程序在技术上永远不会停止运行。我将如何优雅地关闭保持程序存活的后台线程

【问题讨论】:

  • 你需要设置一个通知,这样你也可以杀死这些线程。
  • @StackFlowed 代码到我使用的库创建的那些线程不是开源的,但是无法修改。
  • 当你生成新线程时,你需要添加对通知类的引用,这会在需要时杀死它们。
  • 一般来说,后台线程有一个活动循环,在其迭代的顶部检查它是否应该不再继续。这可能是一个由简单的布尔 API 设置的标志,也可能是它的工作队列是空的,或者......所以在查看 kill 类型方法之前,看看那个特定的库是否可以提供一些东西。
  • @BaseZen 从您的建议的第一部分至今,我没有看到任何东西,但我仍在尽可能深入地挖掘 API 以尝试找到一些东西。但似乎我可能不得不杀死它们,我知道要不惜一切代价避免这种情况,因为突然停止线程可能会发生其他副作用。

标签: java multithreading data-distribution-service


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    杰拉尔多

    【讨论】:

    • 我正在使用 RTI,是的,您对此是正确的。这是我在尝试删除它们时遇到的问题,因为它们是用本机代码创建的,如果不知道要从 DDS 库中使用的 API 调用,就无法在 Java 中优雅地处理。
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-05-28
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        • 2017-03-16
        • 1970-01-01
        • 2012-12-25
        • 1970-01-01
        • 2016-07-01
        相关资源
        最近更新 更多