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