退出Swing应用程序时偶尔发生InterruptedException [英] Occasional InterruptedException when quitting a Swing application

查看:963
本文介绍了退出Swing应用程序时偶尔发生InterruptedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近更新了我的电脑到一个更强大的,与一个四核超线程处理器(i7),因此大量的真正的并发可用。现在当我退出( System.exit(0))一个应用程序(使用Swing GUI)时,我偶尔会 m正在开发:

 删除引用时发生异常:java.lang.InterruptedException 
java.lang.InterruptedException
在java.lang.Object.wait(Native方法)
在java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
在java.lang.ref.ReferenceQueue.remove(ReferenceQueue。 java:134)
at sun.java2d.Disposer.run(Disposer.java:125)
at java.lang.Thread.run(Thread.java:619)

好吧,考虑到它开始发生了一个更多的并发能力的硬件,它与线程,偶尔发生,它显然是一种时间的东西。但问题是堆栈跟踪是如此短。我所有的是上面的列表。它不包括我自己的代码,所以有点难以猜到错误在哪里。



有没有人经历过这样的事情?

编辑:从 System.exit(0)退出Swing应用程序后, 可能是不清洁,但我不想将主框架设置为 EXIT_ON_CLOSE ,因为我想确保没有什么关键的当应用程序退出时,我添加了一个机制,使其在调用 System.exit(0) dispose() c $ c>。所以它应该是很干净,现在,但偶尔的异常仍然发生。它发生在 System.exit(0)被调用之后; dispose()无问题。也就是说,它必须来自关闭挂接:

  mainFrame.dispose(); // 没问题!返回后,所有可见的GUI都消失了。 
//实际上,如果没有其他线程,VM可以在这里终止。
System.exit(0); //从sun.java2d.Disposer.run抛出一个InterruptedException

我甚至尝试明确处置所有 Window 通过循环 Window.getWindows()数组(它包含无人 Dialog s等),但没有什么区别。这个问题似乎与清洁(即在退出之前显式释放本地屏幕资源)无关。



编辑2:将默认关闭操作设置为 EXIT_ON_CLOSE 没有什么区别。 http://www.google.com /search?q=sun.java2d.Disposer.run(Disposer.java:125)发现了几个错误报告,所以也许这的确是Sun的Java2D实现中的一个错误。我可以想象这样的bug可以长时间不固定,因为它们在实践中是相当无害的;从关闭挂钩的异常几乎不伤害任何人。假设这在GUI应用程序中发生,除非 stderr 被指向控制台或日志,否则甚至没有注意到异常。

解决方案

您的Disposer在对remove()的调用中被阻止(删除下一个平台原生资源)。这意味着,当VM退出时,处理器线程(守护线程)不会被自然关闭(您应该期望,因为您通过System.exit()终止它)。



在您的应用程序中有一个非守护进程的线程,当所有的摆动窗口都被释放时,这个线程会使VM不能退出。



解决方案:找到并退出。



通常情况下,如果所有的摆动窗口例如,这个程序将弹出一个窗口,然后退出一旦它被关闭(所有没有调用System.exit()):

  public static void main(String args [])throws Exception {
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.setVisible(true);
}

您也可以尝试在退出之前运行垃圾回收器, / p>

I recently updated my computer to a more powerful one, with a quad-core hyperthreading processor (i7), thus plenty of real concurrency available. Now I'm occasionally getting the following error when quitting (System.exit(0)) an application (with a Swing GUI) that I'm developing:

Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
        at java.lang.Object.wait(Native Method)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
        at sun.java2d.Disposer.run(Disposer.java:125)
        at java.lang.Thread.run(Thread.java:619)

Well, given that it started to happen with a more concurrency-capable hardware, and it has to do with threads, and it happens occasionally, it's obviously some kind of timing thing. But the problem is that the stack trace is so short. All I have is the listing above. It doesn't include my own code at all, so it's somewhat hard to guess where the bug is.

Has anyone experienced something like this before? Any ideas how to start solving it?

Edit: Since quitting a Swing application with System.exit(0) may be "unclean", but I don't want to set the main frame to EXIT_ON_CLOSE because I want to ensure that there's nothing critical going on when the application quits, I added a mechanism so that it executes the main frame's dispose() method before calling System.exit(0). So it should be pretty clean now, but the occasional exception still happens. It happens after the System.exit(0) has been called; dispose() works with no problems. That is, it must be coming from a shutdown hook:

mainFrame.dispose(); // No problem! After this returns, all visible GUI is gone.
// In fact, if there were no other threads around, the VM could terminate here.
System.exit(0); // Throws an InterruptedException from sun.java2d.Disposer.run

I even tried explicitly disposing all Windows by looping through Window.getWindows() array (it contains ownerless Dialogs and such), but it made no difference. This issue seems to have little to do with "cleanness" (i.e. explicitly releasing native screen resources before quitting). It's something else, but what?

Edit 2: Setting the default close operation to EXIT_ON_CLOSE made no difference. http://www.google.com/search?q=sun.java2d.Disposer.run(Disposer.java:125) finds a few bug reports, so maybe this indeed is a bug in Sun's Java2D implementation. I could imagine that bugs like this can go unfixed for a long time, because they're pretty harmless in practice; an exception from a shutdown hook hardly hurts anyone else. Given that this happens in a GUI app, the exception is not even noticed unless the stderr is directed to a console or log.

解决方案

Your Disposer is blocked in a call to remove() (removing the next platform native resource). This means that the disposer thread (a daemon thread) is not being shutdown naturally when the VM exits (which you should expect since you are terminating it via System.exit()).

You have a non-daemon thread in your application which is keeping the VM from exiting when all your swing windows have been disposed.

Solution: find it and cause it to exit.

Normally a swing application exits gracefully if all of its swing windows have been disposed of, for example, this program will pop a window then exit once it is closed (all with no call to System.exit()):

public static void main(String args[]) throws Exception {
    JFrame jf = new JFrame();
    jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    jf.setVisible(true);
}

You might also try running the garbage collector before exiting, just for kicks.

这篇关于退出Swing应用程序时偶尔发生InterruptedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆