构build不在事件派发线程上的Swing / AWT小部件是否安全?

我已经将物质的外观和感觉整合到了我的应用程序中,并遇到了有关它的内部EDT(Event Dispatch Thread)检查例程的几个问题。 物质绝对拒绝在EDT之外构buildUI类。 我已经做了很多Swing / AWT,并且我知道关于EDT的大部分规则。 我使用SwingWorker,SwingUtilties.invokeLater来修改组件。 我总是认为这些组件可以在EDT之外构build ,但是必须在EDT上实现操纵 。 换句话说,您可以在后台构造和设置默认值,但是对pack / setVisible的调用必须是EDT以及任何后续调用组件的调用。

我问的原因是,我有一个特别“结实”的窗口来构build,涉及到许多小部件,状态和资源(很多图标)。 之前,我在SwingWorker的背景方法上构build了窗口,并使窗口在done方法中可见。 从来没有一个单一的问题。 切换到物质后,内部的EDT检查咬我。

我已经能够重构代码来解决这个问题。 我可以在EDT上构build这个不好的解决scheme,因为整个应用程序都会阻塞。 我还可以重构更多的东西,并尽我所能加载EDT以外的所有额外资源。

包装它… 构build Swing / AWT小部件不是在事件派发线程安全吗?

在2004年,Sun已经改变了规则 – 之前,允许您在EDT之外创build组件,并且只有在组件实现后才能进入EDT。

新规定现在写道:

为了避免死锁的可能性,您必须非常小心,Swing组件和模型只能从事件派发线程创build ,修改和查询。

我的这个博客文章给出了更多的细节,包括其他相关文章的链接。 请注意,Sun的所有官方示例都已被重写,并对此非常严格。

从历史上看,可能是随着台式计算机越来越多地使用多核计算机,这激发了重新制定规则 – 线程问题在客户端堆栈上变得越来越明显,并且对美国东部时间准则的要求非常严格他们可以从一开始就被阻止。

没有。

简单的原因是即使EDT在一些罕见的情况下也喜欢僵局,而且一般来说使用Swing( 或者我已经被告知 )很容易死锁UI。 我build议你阅读Kirill's(物质开发)博客的这三篇文章:

  • Swing EDT违规的新文章
  • 与Swing的EDT合作的不成文的规则
  • 严格检查物质中EDT违规情况