您好我有一个独立应用程序,当用户登录abc.lck文件时,当应用程序关闭时会创建它,它会被删除。我使用 addshutdownhook()来删除文件当我的应用程序运行时,电源中断正在关闭电源。我的问题是当我手动关闭系统时,即通过启动 - >关闭,文件没有被删除,我应该使用cofirm dailog box提示用户输入消息来保存更改,就像在MS Word中一样。可以帮助我 感谢你 Chaithu
答案 0 :(得分:6)
addShutdown钩子的常规合约是
Java虚拟机关闭以响应两种事件:
当最后一个非守护程序线程退出或调用exit(等效,System.exit)方法时,程序正常退出,或者
虚拟机将响应用户中断(例如键入^ C)或系统范围的事件(例如用户注销或系统关闭)而终止。
关闭钩子只是一个初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有挂钩都完成后,如果启用了finalization-on-exit,它将运行所有未读取的终结器。最后,虚拟机将停止。请注意,守护程序线程将在关闭序列期间继续运行,如果通过调用exit方法启动关闭,则非守护程序线程也将继续运行。
在极少数情况下,虚拟机可能会中止,即停止运行而不会干净地关闭。当虚拟机在外部终止时会发生这种情况,例如Unix上的SIGKILL信号或Microsoft Windows上的TerminateProcess调用。如果本机方法因例如破坏内部数据结构或尝试访问不存在的内存而出错,则虚拟机也可能中止。如果虚拟机中止,则无法保证是否将运行任何关闭挂钩。
因此在关机期间,Windows机器可能会调用TerminateProcess,因此可能不会调用您的关闭挂钩。
答案 1 :(得分:2)
使用deleteOnExit方法而不是添加shutdownhook。不过,请看一下这个sample,
class Shutdown {
private Thread thread = null;
protected boolean flag=false;
public Shutdown() {
thread = new Thread("Sample thread") {
public void run() {
while (!flag) {
System.out.println("Sample thread");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException ie) {
break;
}
}
System.out.println("[Sample thread] Stopped");
}
};
thread.start();
}
public void stopThread() {
flag=true;
}
}
class ShutdownThread extends Thread {
private Shutdown shutdown = null;
public ShutdownThread(Shutdown shutdown) {
super();
this.shutdown = shutdown;
}
public void run() {
System.out.println("Shutdown thread");
shutdown.stopThread();
System.out.println("Shutdown completed");
}
}
public class Main {
public static void main(String [] args) {
Shutdown shutdown = new Shutdown();
try {
Runtime.getRuntime().addShutdownHook(new ShutdownThread(shutdown));
System.out.println("[Main thread] Shutdown hook added");
} catch (Throwable t) {
System.out.println("[Main thread] Could not add Shutdown hook");
}
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException ie) {}
System.exit(0);
}
}