为什么使用invokeLater很重要?

时间:2013-10-03 19:02:33

标签: java swing event-dispatch-thread invokelater

我最近找到了一个示例代码:

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}

createAndShowGUI()方法打开用户界面窗口。然后我尝试修改代码如下:

public static void main(String[] args) {
    createAndShowGUI();
}

两个版本都同样有效。有什么区别?

4 个答案:

答案 0 :(得分:10)

99%的时间任一代码都可以使用。

但是,Swing的设计使得Swing组件的所有更新都应该在Event Dispatch Thread(EDT)上完成。有关详细信息,请阅读Concurrency上的Swing教程。

问题是1%的时间可能无法正常工作。您不想浪费时间尝试调试随机问题。

答案 1 :(得分:4)

SwingUtilities.invokeLater确保代码在Event Dispatch Thread(EDT)上执行。 Swing是单线程的,所有组件实例化和显示都应该在EDT上进行。事情看起来似乎不然,但你可能会遇到问题。

答案 2 :(得分:3)

Swing具有单线程基于事件循环的设计,并且不是线程安全的,只有线程安全部分是一组用于将控制转移到Swing事件循环的invokeXXX()方法。

你的“破解”代码工作得很好,因为没有别的东西试图同时从事件循环中触及Swing数据结构的相同部分。

答案 3 :(得分:3)

JVM启动的“主”线程不是事件调度线程。

来自The Event Dispatch Thread

  

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