如何防止关机钩子陷入死锁?
Posted
技术标签:
【中文标题】如何防止关机钩子陷入死锁?【英文标题】:How to prevent shutdown hook from getting deadlock? 【发布时间】:2015-08-31 22:41:28 【问题描述】:我看到@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();
);
但是我不知道如何区分我的shutdown hook中是否有死锁,如果有,如何解决。
【问题讨论】:
你试过 kill -3 吗?还是在 wows jstack 上? 我不知道该怎么做?! @ThomasKrieger 你用的是windows还是linux? 我正在使用窗口@ThomasKrieger @Tej Kiran ,你的问题解决了吗?!怎么样? 【参考方案1】:首先 - 您的 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();可能会锁定你的执行。
删除他们一个我的一个,看看是什么导致你的阻塞。然后进去看看到底是什么阻碍了他们。
【讨论】:
【参考方案2】:我自己的回答:
你知道它似乎与关闭挂钩无关!我使用 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);
);
【讨论】:
以上是关于如何防止关机钩子陷入死锁?的主要内容,如果未能解决你的问题,请参考以下文章