如何确保长时间运行的Java线程永不消亡

如何确保长时间运行的Java线程永不消亡,java,multithreading,exception,Java,Multithreading,Exception,我有一个长期运行的线程,做家务的任务。由于系统不会立即受到影响,因此很难检测到线程的故障。我想确保这根线永远不会死。我的理解是,只要代码捕获了所有可以丢弃的东西,它就永远不会消亡。以下是示例代码: while (true) { try { // house keeping logic } catch (Throwable t) { // do not do anything } } 我的理解正确吗?有没有更好的方法托管长时间运行的后台任务

我有一个长期运行的线程,做家务的任务。由于系统不会立即受到影响,因此很难检测到线程的故障。我想确保这根线永远不会死。我的理解是,只要代码捕获了所有可以丢弃的东西,它就永远不会消亡。以下是示例代码:

while (true) {
    try {
        // house keeping logic
    } catch (Throwable t) {
        // do not do anything
    }
}

我的理解正确吗?有没有更好的方法托管长时间运行的后台任务?我知道ScheduledExecutorService可以定期安排任务,但如果任务需要不断检查某些资源,则将所有内容都放在while循环中可能更有效

如果内务管理逻辑包括一些可归类为周期性任务的任务,例如每20秒检查一次与某项服务的连接,那么最好使用

一些

如果TimerTask中发生了OOM之外的任何事情-它不会影响负责任务调度的计时器。

以下几点:

我强烈建议您使用ScheduledExecutorService或您正在使用的任何工具或框架可能提供的其他等效功能,例如Spring中的@Scheduled。在这些情况下,有许多考虑因素不是很明显,一个建立良好且维护良好的库将处理这些问题

第二,以这种方式毫不拖延地进行民意调查以寻求改变是很少见的。例如,典型的场景可能要求您关闭与1分钟内没有响应的计算机的连接。对于这种循环,您不需要像上面的循环那样不断地检查。至少,您应该包括对Thread.sleep的调用,以防止过度使用资源。这是ScheduledExecutorService很好地处理的另一个问题


最后,您应该包括一些在应用程序终止时优雅地退出循环的方法。一个简单的布尔运行=真;在类上运行就足够了,然后在运行{…}时将循环更改为:while。当您想退出时,只需设置running=false;循环将退出。

您不能保证线程长时间运行。但是,如果线程出现问题,可以重新生成逻辑

您可以做的是让一个监视程序检查线程是否每x分钟运行一次

请注意,如果JVM关闭或崩溃,观察程序将失败。如果要在JVM关闭时重新启动线程,则需要进行外部监视。为此,您可以使用以下工具:


在某些情况下,线程将与整个JVM一起消亡,例如OutOfMemoryError;没有不朽的过程。这取决于资源,但将所有内容放在while循环中几乎肯定不是最有效的方法。该线程运行在哪种应用程序中?捕获所有可丢弃的内容只会捕获已检查的异常,哈?!我的错误,显然是深夜。我将编辑我的答案
public class LongRunningThread extends Thread {
    private volatile boolean IS_RUNNING = true;

    @Override
    public void run() {
        while (IS_RUNNING) {
            try {
                // actions
                this.houseKeep();
            } catch (Exception e) {
            }
        }
    }

    private void houseKeep() {
        // housekeeping logic here
    }

}

class ThreadWatcher {
    private Thread threadToBeWatched;

    public ThreadWatcher(Thread threadToBeWatched) {
        this.threadToBeWatched = threadToBeWatched;
    }

    @Scheduled(cron = "*/1 * * * *")
    public void checkStatus() {
        if (!threadToBeWatched.isAlive()) {
            // Logic to restart the thread.
        }
    }
}