假设我正在运行计时器任务,并在加载时创建了一个新资源,如下所示。这是一个监视过程,可以无限期运行,并且是从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的当前解决方案,但是我无法决定要使用哪种解决方案。当我阅读所有解决方案时,似乎没有一个干净的解决方案可以关闭此设置中的资源,但想知道首选的方法。
如果您需要更多详细信息,请告诉我。
答案 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