1

在 Swing 中,GUI 应该只由 EDT 更新,因为 GUI 组件不是线程安全的。

我的问题是,如果我有一个单独的线程,除了 EDT,它专门用于更新特定组件,并且我的程序中的任何其他线程都没有访问这个组件,只有这个专用线程,可以吗?在我的情况下,我有JTable一个线程从网络接收信息并更新表(不使用EventQueue.invokeLater)。所有其他组件都从 EDT 更新。到目前为止我还没有看到问题,我想知道最终是否会出现错误。

UPDATE 我的目的是实时更新表。数据不断地来自网络,为此我专门为表专门设置了 1 个线程,以便在它们到来时不断更新它。如果我使用 SwingUtilities.invokeLater,这意味着表将在 EDT 可用时更新。是不是swing应该是用来满足实时更新需求的?

4

5 回答 5

6

Instead of trying to reason about whether it will or won't work, I would just stick to the well-known 'rule' which is that you should only interact with GUI components using the event dispatching thread. When you receive data from the network, just update the table using SwingUtilities.invokeLater (or invokeAndWait).

You might not see problems straight away, but it's quite possible you might do in the future.

于 2010-09-04T17:04:15.437 回答
4

There are a few methods documented as thread-safe. I believe a few less in JDK7, because it turns out some of them are unimplementable as thread-safe. For the most part Swing is thread-hostile - it has to be used from the AWT EDT thread. This is largely because it uses EventQueue.invokeLater internally at "random". Also there is hidden shared state (you can change the PL&F without having to tell each component for instance). Some classes you may be able to treat as thread-agnostic, but they are not documented as such.

So the answer is, always use the EDT for Swing. As with most threading bugs, you might seem to get away with it and then suddenly fail in production. The bug is likely to be difficult to diagnose and reproduce (particularly if it only happens in production on certain systems). Fixing a code base that is severely broken may not be fun. Keep it clean from the start.

于 2010-09-04T17:02:15.270 回答
2

You must update GUI components on the EDT. Period. (There are a couple of legacy exceptions to this rule - but they were all silently putting things over to the EDT anyway). The EDT operates as a message pump (as most windowing systems do) - you have to live within that constraint if you want to update GUI components.

If you want your table to update quickly, keep the EDT clean - don't put any huge load onto it.

If you are working with updating live tables, I strongly recommend that you take a look at GlazedLists - they have a very, very good SwingThreadProxyList implementation that takes care of efficiently posting updates to the EDT. You have to agree to drink the GlazedLists koolaid to go this route, but it is mighty tasty koolaid (I love GL).

于 2010-09-04T17:50:17.450 回答
1

Swing 不应该用于实时更新需求吗?

不可以。您可能能够以足够的速度更新您的数据模型,但 GUI 通常是从属的。您可以利用环境中的任何网络延迟。或者,您可能需要考虑 Oracle 的Sun Java Real-Time System之类的东西。

您可以通过保持更新简短并使用最少的正确同步来提高 EDT 的“活跃性”。这里讨论了几种替代方案。

于 2010-09-04T17:50:34.463 回答
1

这是一个绝对规则,除非你想要竞争条件。事件调度线程足够快,我们的 CCTV 应用程序的显示不需要 hack。

于 2010-09-04T18:10:54.337 回答