如何正常停止计时器任务?

时间:2018-10-16 21:54:54

标签: 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();
  }

}

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

我研究了从关闭挂钩到JMX的当前解决方案,但是我无法决定要使用哪种解决方案。当我阅读所有解决方案时,似乎没有一个干净的解决方案可以关闭此设置中的资源,但想知道首选的方法。

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

1 个答案:

答案 0 :(得分:1)

一种方法是使用Runtime.addShutdownHook注册一个新的关闭挂钩线程。它将涵盖常规关机情况,例如收到的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无法通过设计来处理,因此没有完美的方法来关闭资源。根据{{​​3}}的建议,可以使用包装脚本来查找JVM消失的情况:

#!/usr/bin/env bash

java MyMain
wait
# cleanup resources if needed