【问题标题】:Can JVM kill a timer/daemon thread while app is running (abruptly)?JVM可以在应用程序运行时(突然)杀死计时器/守护线程吗?
【发布时间】:2016-03-23 23:59:28
【问题描述】:

我打算创建一个行为类似于计时器的线程。我将在特定延迟后使用 sleep 重新触发操作..
我担心 JVM 是否会在不关闭应用程序的情况下突然终止我的线程,
因此,如果应用程序正在运行并且此线程终止,我的功能将无法获得新的令牌。
要么我将不得不编写一些手动功能来重新启动它。

所以我的问题是:JVM 可以突然杀死任何线程吗?

安排任务的最佳解决方案是什么?由于我的任务执行时间是在运行时到来的,所以我不能使用固定调度执行器。

【问题讨论】:

    标签: java jvm java-8 java-7 jvm-crash


    【解决方案1】:

    据我所知,JVM 不会随机终止任何线程,因为这会导致所有 Java 程序的行为未定义。但是,如果没有不是守护线程的正在运行的线程,JVM 将自行关闭并杀死任何标记为守护线程的正在运行的线程。

    引用Thread::setDaemon:

    将此线程标记为守护线程或用户线程。当唯一运行的线程都是守护线程时,Java 虚拟机退出。

    要重复安排任务,您应该尽可能使用ScheduledExecutorService。您在运行时得到延迟这一事实并不能阻止您这样做。

    另见:Invoking a java Timer-Task from the timer thread

    【讨论】:

      【解决方案2】:

      所以我的问题是 jvm 可以突然杀死任何线程。

      通常,这取决于线程及其创建方式以及 JVM abruptly kill 的含义。 JVM 在关闭时会通知所有守护程序。请看:

      安排任务的最佳解决方案是什么。由于我的任务执行时间是在运行时到来的,所以我不能使用固定调度执行器。

      就您而言,我认为最好的解决方案是使用提供的实现。为什么不能使用ScheduledExecutorService,我不明白运行时参数。看看 Stefan Dollase 的回答,因为他提供了一些关于它的用法的更多见解。

      【讨论】:

      • 所以我不能使用 ScheduleExecutor 因为我得到的时间表来自预定线程。所以第一次线程执行会给我第二次执行的时间表。突然意味着如果jvm内存不足或任何其他类型的错误,它会清理线程吗?并且可以杀死我的线程或尝试重新启动它?
      • 这取决于JVM如何关闭。通常,JVM 会尝试对所有线程进行正常关闭。但它只有在没有任何非守护线程运行时才会关闭。如果线程中有异常,则该线程会像任何其他线程一样退出。如果您想知道如何在线程中捕获异常,请查看stackoverflow.com/questions/6546193/…
      【解决方案3】:

      看看是不是守护线程,直到:

      1. 分配给线程的工作已完成。
      2. System.exit() 被调用。
      3. 如果发生错误或异常。
      4. 如果 JVM 已停止。

      这里只涉及第三个问题。要解决此问题,请使用捕获 Throwable 的 try-catch(这将捕获所有内容),并在 catch 中编写一种机制来重新运行该函数。

      【讨论】:

        猜你喜欢
        • 2013-11-04
        • 1970-01-01
        • 1970-01-01
        • 2018-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多