5

我在这里看到@Tej Kiran 提出的一个问题,这正是我的问题,但没有得到回答,最后一条评论说:

“您知道您的应用程序中是否注册了任何关闭挂钩,或者您正在使用的任何库是否有关闭挂钩?关闭挂钩是一个线程,如果该线程中存在死锁导致它永远不会终止,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();
        }
    }
});

但是我不知道如何区分我的关闭挂钩中是否存在死锁,如果有,如何解决。

4

2 回答 2

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(); 可能会锁定您的执行。

删除他们一个我的一个,看看是什么导致你的阻塞。然后进去看看到底是什么阻碍了他们。

于 2015-06-16T16:17:08.400 回答
0

我自己的回答:

你知道它似乎与关闭挂钩无关!我使用 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);
                    }
                });
于 2015-06-17T05:48:13.220 回答