【问题标题】:EventQueue.invokeLater vs Thread.startEventQueue.invokeLater vs Thread.start
【发布时间】:2014-04-25 21:15:08
【问题描述】:

对于 Swing 应用程序,我们使用EventQueue.invokeLater() 有什么原因吗? Thread.start() 不应该以同样的方式工作吗?

Thread.start 的另一个优点是我们可以告诉线程中断,因为EventQueue.invokeLater 没有为我们提供Thread 对象。

【问题讨论】:

    标签: java multithreading swing


    【解决方案1】:

    您应该使用 EventQueue.invokeLater 进行所有 GUI 更新,因为 Swing 在某种程度上是单线程的。见http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threading

    您可以启动线程进行计算等,但应使用 invokeLater 更新 GUI。

    【讨论】:

    • 因此,如果您不进行任何 GUI 更新,而是进行“模型”更新,是使用 Thread.start 还是应该使用 EventQueue.il?
    • @Archimedes Trajano:如果您的模型更新会长时间阻塞 GUI,您应该在单独的线程中更新模型。 “长时间”超过200毫秒。
    • 不,这更像是将状态文本设置为“正在停止...”。但听起来那样做是可以的。
    • So if you're not doing any GUI update, but doing "model" update is it fine to use Thread.start - 不,因为对模型的更改会导致 GUI 组件重新绘制自身。
    • @camickr 完全适用于所有摇摆模型,这就是它应该的样子!但他们似乎在谈论一种“残缺的模型”,即不通知任何听众的模型,参见 Gilbert 的示例,因此可能是一种边缘情况,只要控制器确保 EDT 上的更新
    【解决方案2】:

    启动 Swing 应用程序的两个选项是:

    EventQueue.invokeLater()
    

    SwingUtilities.invokeLater()
    

    我的偏好是使用 SwingUtilities。他们都将可运行文件放在Event Dispatch thread (EDT) 上。您不需要 EDT 的句柄。

    您的代码要么在 EDT 上,要么另一个调用 invokeLater() 方法会将可运行对象放在 EDT 上。您可以使用 SwingUtilities.isEventDispatchThread() 方法调用来确定任一条件。

    Thread.start() 方法适用于您自己的工作线程。或者,如果您愿意,可以将 javax.swing.SwingWorker 类用于您自己的 Swing 工作线程。

    这是我用来启动我编写的每个 Swing 应用程序的样板。

    package com.ggl.game2048;
    
    import javax.swing.SwingUtilities;
    
    import com.ggl.game2048.model.Game2048Model;
    import com.ggl.game2048.view.Game2048Frame;
    
    public class Game2048 implements Runnable {
    
        @Override
        public void run() {
            new Game2048Frame(new Game2048Model());
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Game2048());
        }
    
    }
    

    简明扼要。这个类做了 3 件事。

    1. 将 Swing 应用程序放在 EDT 上。
    2. 实例化 Swing 应用程序模型。
    3. 实例化 Swing 应用程序 JFrame。

    您可以在我的 Java 文章中查看 2048 Swing application 的其余部分。

    【讨论】:

    • 谢谢,这通常是我做事的方式,但这不适用于我的问题。
    • 顺便说一句,2048 年的实现很好
    • @Archimedes Trajano:答案不仅适合您,也适合后来出现并通过搜索找到此问题的每个人。
    • 又一个瘫痪的(有些人称其为被动式,不过 ;-) 模型实现 当其状态发生变化时,模型会通知其关联的视图和控制器。跨度>
    • SwingUtilities.invokeLater(…) 只是委托给EventQueue.invokeLater(…)。看不到您喜欢使用SwingUtilities 的备份...顺便说一下,您可以javax.swing.Timer 类用于您的“自己的Swing 工作线程”。 Swing 的 Timer 只是在 EDT 内传递 ActionEvents。
    猜你喜欢
    • 1970-01-01
    • 2011-09-05
    • 2014-05-08
    • 2012-09-18
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多