2

回复:在 Event-Dispatch 线程上创建 Swing 对象的要求。

我正在开发一个应用程序,其目的是监视和显示各种远程嵌入式服务器的状况。我对 Java 很陌生,我对 Swing 对象和 EDT 的要求的理解是不完整的。

主 GUI 在 EDT 上以通常的方式启动,如下所示,

    javax.swing.SwingUtilities.invokeLater(new Runnable() {

        public void run() {
            createAndShowGUI();
        }
    });

用户然后可以选择对应于远程机器中的一个或另一个的一个或多个菜单选项。这样的效果就是每次新建一个线程如下

                new Thread(new VoterStatus(itemNumber)).start();

它调用 VoterStatus 的类“run”方法,该方法又创建一个带有 JFrame 的新窗口。新线程是 VoterStatus 类的一个实例,然后询问(TCP 等)指定的特定远程(itemNumber),收集各种信息位并在 JFrame 中显示它们。

可能有任意数量的此类线程对应于 VoterStatus 的一个实例,它们都更新它们自己的窗口。这些不同的窗口/JFrame/任务之间没有数据共享。

这似乎工作得很好,但是安全吗?

我是否违反了在 EDT 上创建 Swing 组件的规则?

使用 SwingWorker 类是否有益?

我将不胜感激在此类问题上更有经验的 Java 程序员的任何评论。

谢谢史蒂夫

4

4 回答 4

5

来自 Swing 教程中标题为The Event Dispatch Thread的部分

一些 Swing 组件方法在 API 规范中被标记为“线程安全”;这些可以从任何线程安全地调用。所有其他 Swing 组件方法都必须从事件分派线程中调用。忽略此规则的程序可能在大多数情况下都能正常运行,但会出现难以重现的不可预测的错误。

我总是在 EDT 上调用我的方法,所以我不会浪费时间追逐小精灵。

编辑:

我刚刚阅读了另一篇文章,其中指出注释“线程安全”已从 JDK7 API 中的许多方法中删除。http://forums.oracle.com/forums/thread.jspa?threadID=2167051。这似乎是确保影响 GUI 的所有方法都在 EDT 上执行的另一个原因。

于 2011-02-01T04:31:24.037 回答
2

@camickr 拥有它的权利。不正确同步的程序在大多数情况下似乎都可以正常工作,但结果并不可靠。这里讨论了几种相关的方法。是一个特别方便的接口实现,在事件调度线程上运行。SwingWorkerFutureprocess()

于 2011-02-01T05:13:14.643 回答
0

我并没有真正回答我自己的问题,但我确实要感谢那些回答并提出一两个后续问题的人。

Rogash 评论说,如果我只是在 EDT 上创建 GUI,我会没问题,但这似乎不太符合对规则的严格解释?

附加线程是在 EDT 中创建的,但它们仍然是单独的线程。

虽然可能需要更好地分离 GUI 和通信,但我预计这会给主要 GUI 代码增加相当大的复杂性,因为它必须确定哪个窗口引发了各种事件,然后更新正确的窗口,更不用说之间的通信了各种线程和主 GUI 线程。也许我夸大了这个困难(我还没有设计或考虑过如何编码)但它似乎更复杂。每个线程/JFrame 已经有几个导致潜在事件的 JToggleButton 数组(30 个元素)和 10 个左右的 JTextField 数组,它们具有相同数量的需要更新的元素。

当然,如果我的方法不安全,我将不得不改变它,就是这样!

实际上,我想知道我是否最好让事情保持原样,并使用互斥锁或信号量来确保一次只有一个线程访问 Swing 方法。确实没有长时间的用户操作或任何其他活动需要很长时间,只是收到了大量需要更新屏幕显示的 TCP 或 UDP 数据包。

再次感谢史蒂夫

PS 我试图在这个论坛上注册,但我认为这个讨论将保留在我未注册的角色中。

于 2011-02-02T05:19:03.080 回答
0

您可能是安全的,但您可以通过在 EDT 中创建其他 UI 组件来确保这一点,就像您在主应用程序中所做的那样。

但是,我会建议一种不同的方法。Thread与其启动为每个 new 创建窗口和东西的 new ,不如VoterStatus在 EDT 中创建 UI 组件以响应ActionEvents菜单或其他内容,并仅在不同的线程中处理网络内容。然后获取结果并使用 EDT 显示它们。正如您所建议的那样, aSwingWorker是理想的选择 - 这正是它的设计用途。这对我来说代表了更清晰的分离,尽可能地将 UI 内容与网络内容分开。

于 2011-02-01T05:11:15.477 回答