代码之家  ›  专栏  ›  技术社区  ›  s7vr

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

  •  0
  • s7vr  · 技术社区  · 7 年前

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

    问:当我使用命令行停止进程时,我想确保调用了resource close方法。我需要做什么改变?

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

    如果你需要更多的细节,请告诉我。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Karol Dowbecki    7 年前

    一种方法是使用 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(); 
      }
    
    }
    

    in this answer 可以使用包装器脚本查找JVM:

    #!/usr/bin/env bash
    
    java MyMain
    wait
    # cleanup resources if needed