我已经看到@Tej Kiran提出的一个问题here,这正是我的问题,但没有回答,最后的评论说:
"您知道您的注册中是否有任何关闭挂钩? 应用程序,或者如果您正在使用的任何库具有 关机钩?关闭钩子是一个线程,如果有的话 该线程中的死锁导致它永远不会终止,JVM会 永不退出。"
我的程序中有一个方法关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown Hook") {
@Override
public void run() {
System.out.println("---------------");
System.out.printf("%d threads running%n", Thread.activeCount());
Map<Thread, StackTraceElement[]> threads = Thread
.getAllStackTraces();
for (Entry<Thread, StackTraceElement[]> e : threads.entrySet()) {
Thread t = e.getKey();
System.out.printf("%s\t%s\t%s%n", t.getName(),
t.isDaemon(), t.isAlive());
StackTraceElement[] elements = e.getValue();
for (StackTraceElement trc : elements) {
System.out.println("\t" + trc);
}
}
System.out.println("---------------");
try {UIUtil.cancelAllTasks();} catch (Throwable e) {e.printStackTrace();};
try {mehad.io.port.ScannerManager.disableAutoHandshake();} catch (Throwable e) {e.printStackTrace();};
try {mehad.io.port.ComPortInterface.getInstance().close();} catch (Throwable e) {e.printStackTrace();};
try {
if (lockStream != null) {
lockStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
但是我不知道如何区分我的关机钩子是否存在死锁,如果有的话,如何解决它。
答案 0 :(得分:0)
首先 - 你的ShutdownHook工作正常。 现在关于死锁。
您知道在您的注册中是否注册了任何关闭挂钩 应用
我很确定没有这样的东西,因为如果某个第三方部分出现另一个死锁,那么即使没有你的钩子,你的应用也会被锁定。我认为这不是事实,因为你抱怨你的代码 - 所以没有你的钩子它工作正常,所以没有第三方钩子。
你的死锁就在其中一个电话中:
try {UIUtil.cancelAllTasks();} catch (Throwable e) {e.printStackTrace();};
try {mehad.io.port.ScannerManager.disableAutoHandshake();} catch (Throwable e) {e.printStackTrace();};
try {mehad.io.port.ComPortInterface.getInstance().close();} catch (Throwable e) {e.printStackTrace();};
try {
if (lockStream != null) {
lockStream.close();
}
事实上,它们被包装到try / catch块中并不能防止它们死锁。
没有提供有关这些方法的代码。甚至是lockStream.close();可以锁定你的执行。
将它们移除一个,看看导致阻塞的原因。然后进去看看实际阻挡它们的是什么。
答案 1 :(得分:0)
我自己的回答:
你知道它似乎与shutdown hook无关!我使用WindowListener来关闭MainFrame,我添加了一个条件,如果要显示用户是否想要离开的消息?如果答案是肯定的,则转到System.exit(0)。之前在关闭窗口之前没有要求的条件。现在它工作正常!甚至在一些以前没有工作的稀有机器上。但是我仍然不知道它添加的那条线是如何工作的!如果有人能解释它现在如何正常工作,我将不胜感激!
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
try {
ComPortInterface.getInstance().close();
} catch (Exception e) {
e.printStackTrace();
}
//this if condition is added to ask if you want to exit or not
if (MessageUtil.showYesNo("Exit ?")) {
System.exit(0);
}
// System.exit(0);
}
});