1

这主要是一个理论问题。下面的例子让我想到了它,但它可能不是最好的例子。请假设以下原因是具体的,目前无法解决。

我一直在运行的程序有一个可选的调试框架,它是在程序启动时创建的,用户按下按钮/键盘快捷键可以看到它。

我的问题是,由于我在 EDT 上有冗长的进程,如果它由于某种原因挂起或失败,我希望立即查看,而不是等待该线程结束运行,以更新调试日志框架。

我的解决方案是为两个由单独线程更新的单独 GUI 设置两个单独的 EDT。

这是可能的,还是我不能这样做?我还没有找到任何可以告诉我如何操作的在线资源。我知道 EDT 应该是单线程的,但如果我保持线程解开,我可以有两个吗?请?

4

1 回答 1

5

答案很简单:不,您不能拥有 2 个EDT,这是不可能的。但是您并没有被冻结的 GUI 困住,您有一些可用的选项。

首先,两个重要的规则:

  1. 永远不要在 EDT 中进行冗长的计算。曾经。
  2. 切勿从 EDT 外部操作 Swing 组件。曾经。

违反第一条规则将导致您的 GUI 被冻结,并且在此期间不会处理任何类型的事件。这包括在计算期间要更新的 GUI,直到计算完成后才会出现。

后者经常被忽略,大部分时间都会被忽视,但它可以 - 并且将会 - 咬你的屁股,然后大多数时候回去修复它是一个巨大的皮塔饼。所以从一开始就以正确的方式去做。会发生什么?组件可能会突然显示为损坏状态,它们可能会显示为白色,或者整个应用程序可能会冻结,因为 EDT 和您的其他线程之间存在死锁(在那里,完成了)。遵守Oracle Swing 线程策略


那么,如何避免在用户按下按钮后对 EDT 进行冗长的计算呢?选项:

  • 使用SwingWorker。优点:有一个done()你可以使用的方法,一旦工作人员完成,它就会在 EDT 中自动执行。还实现了Future接口,因此可用于返回结果。
  • 您可以创建自己的Runnable并在那里进行计算。
  • 使用 Java 为并行执行提供的任何其他方式。

好的,以及如何避免从 EDT 外部操纵 GUI

  • 在那里调用SwingUtilities.invokeLater()并执行 Swing 操作。
  • done()如上所述使用 SwingWorkers方法。

如果您遵循这两条规则,您的 Swing GUI 将处于一个更好的状态,您可以更多地关注您的应用程序开发而不是 Swing 问题。

于 2013-05-10T10:00:43.027 回答