我最近找到了一个示例代码:
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
createAndShowGUI()
方法打开用户界面窗口。然后我尝试修改代码如下:
public static void main(String[] args) {
createAndShowGUI();
}
两个版本都同样有效。有什么区别?
答案 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
启动的“主”线程不是事件调度线程。
一些Swing组件方法在API规范中标记为“线程安全”;这些可以从任何线程安全地调用。 必须从事件派发线程调用所有其他Swing组件方法。忽略此规则的程序可能在大多数情况下正常运行,但会遇到难以重现的不可预测的错误。