Java 如何优雅地停止计时器任务?

Java 如何优雅地停止计时器任务?,java,Java,假设我已经运行了计时器任务,并创建了一个新的加载资源,如下所示。它是一个设置为无限期运行的监视进程,从jar内部调用 比如说 主类 public class MyMain { public static void main(String[] args ) { TimerTask task = new MyTimerTask(); Timer timer = new Timer(); timer.scheduleAtFixedRate(task,0,300

假设我已经运行了计时器任务,并创建了一个新的加载资源,如下所示。它是一个设置为无限期运行的监视进程,从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();
  }

}
问题:当我使用命令行停止进程时,我希望确保调用ResourceClose方法。我需要做哪些更改

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


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

一种方法是使用注册一个新的关机挂钩线程。它将涵盖常规关机场景,如收到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,因此没有完美的方法来关闭资源。正如建议的那样,可以使用包装器脚本查找JVM:

#!/usr/bin/env bash

java MyMain
wait
# cleanup resources if needed

使用TimerTask.cance?为什么关闭此资源如此重要?编写可能不一致的文件?shutdownhook应该涵盖所有常见的场景,SIGKILL是您不应该期望的,因为它不利于数据的一致性,这就是为什么数据库需要非常低级别的文件系统访问以及以特定方式刷新和同步的原因。如果你的系统中经常发生这样的事情,那就把它清除掉吧。。。。也许你可以采取不同的方法,因为即使你能解决这个问题,你仍然有可能系统断电或复位