我最近将我的计算机更新为功能更强大的计算机,配备四核超线程处理器 (i7),因此可以提供大量真正的并发性。现在,在退出( )我正在开发的应用程序(带有 Swing GUI)时,我偶尔会遇到以下错误:System.exit(0)
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)
好吧,鉴于它开始发生在具有更高并发能力的硬件上,并且与线程有关,而且偶尔会发生,这显然是某种时间问题。但问题是堆栈跟踪太短了。我只有上面的清单。它根本不包含我自己的代码,因此很难猜测错误在哪里。
有没有人经历过这样的事情?任何想法如何开始解决它?
编辑:由于退出 Swing 应用程序System.exit(0)
可能是“不干净的”,但我不想将主框架设置为,EXIT_ON_CLOSE
因为我想确保应用程序退出时没有任何关键的事情发生,我添加了一个机制以便它执行dispose()
调用前主框架的方法System.exit(0)
。所以现在应该很干净了,但偶尔还是会发生异常。它发生在System.exit(0)
被调用之后;dispose()
工作没有问题。也就是说,它必须来自关闭挂钩:
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
我什至尝试Window
通过循环遍历Window.getWindows()
数组(它包含无主Dialog
s 等)来显式处理所有 s,但它没有任何区别。这个问题似乎与“清洁度”(即在退出前显式释放原生屏幕资源)关系不大。这是另一回事,但什么?
编辑2:将默认关闭操作设置为EXIT_ON_CLOSE
没有区别。http://www.google.com/search?q=sun.java2d.Disposer.run(Disposer.java:125)发现了一些错误报告,所以也许这确实是 Sun 的 Java2D 实现中的错误。我可以想象这样的错误可能会在很长一段时间内无法修复,因为它们在实践中是无害的;关闭挂钩的异常几乎不会伤害其他任何人。鉴于这发生在 GUI 应用程序中,除非将stderr
其定向到控制台或日志,否则甚至不会注意到异常。