java - 如何优雅地停止定时器任务?

标签 java

假设我已经运行计时器任务并在加载时创建一个新资源,如下所示。它是一个设置为无限期运行的监视进程,并从 jar 内部调用。

例如。

主类

public class MyMain  {

   public static void main(String[] args ) {

     TimerTask task = new MyTimerTask();
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(task,0,30000)

  }

}

定时器任务

class MyTimerTask extends TimerTask  {

  private static final MyResource resource;

  static {
    resource = new MyResource();
  }

  @Override
  public void run() {
       ....
  }

  public void close() {
     resource.close();
  }

}

问题:当我使用命令行停止进程时,我想确保调用资源关闭方法。我需要做出哪些改变?

我已经查看了当前的解决方案,从关闭 Hook 到 JMX,但我无法决定采用哪一个。当我阅读所有解决方案时,我认为没有一个干净的解决方案可以关闭此设置中的资源,但我想知道首选方法。

如果您需要更多详细信息,请告诉我。

最佳答案

一种方法是使用 Runtime.addShutdownHook 注册一个新的关闭钩子(Hook)线程。 。它将涵盖常规关闭场景,例如收到的 SIGINT。

public static void main(String[] args) {
  TimerTask task = new MyTimerTask();
  Timer timer = new Timer();
  timer.scheduleAtFixedRate(task, 0, 1000);

  Runtime.getRuntime().addShutdownHook(new Thread(MyTimerTask::close));
}

public static class MyTimerTask extends TimerTask {

  public static void close() {
    resource.close(); 
  }

}

因为总会有 JVM 突然退出的情况,例如: SIGKILL 是设计无法处理的,不会有完美的方法来关闭资源。按照建议in this answer可以使用包装器脚本来查找 JVM 是否消失:

#!/usr/bin/env bash

java MyMain
wait
# cleanup resources if needed

关于java - 如何优雅地停止定时器任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52844536/

相关文章:

Java 和 JavaScript 本质同时存在

java - 环境配置管理?

java - 有什么方法可以创建一个通用列表,在其中添加类型和子类型?

java - 如何实现背景屏幕颜色过渡?

java - 如何配置磁盘缓存 jcs

java - Java 中的嵌套映射或组合键

java - 要映射的 JAXB 节点

Java数组返回错误值

Java-我没有从 for 循环和 if 语句中获得输出

java - 将字节数据写入目录