我不能回答这个问题的任何其他线程,但我想知道有什么区别,让我们说:
public static void main(String[] args) {
new GUIObject();
}
或:
public static void main(String[] args) {
SwingUtilies.invokeLater(new Runnable() {
public void run() {
new GUIObject();
}
});
}
我一直在使用第一种方法,但我在YouTube上看到一些使用后一种方法的视频,它似乎做同样的事情。
您的Swing GUI需要在事件分派线程(EDT)上运行。当Java虚拟机启动main
函数时,它不在EDT上。因此,您可以通过使用invokeLater()
来确保您的GUI在EDT上启动。
可能令人困惑的是,如果你不使用invokeLater()
的东西可能仍然工作。那么有什么好大惊小怪的呢?总有一天,在你最意想不到的时候,事情不顺心了,这就是原因。
更多信息可以在这里找到:Initial Threads.
invokeLater接受放置在事件调度线程队列中的Runnable,它最终将在EDT上运行。人们在EDT上修改和查询Swing对象的状态只是因为Swing不是线程安全的,因此,如果始终使用相同的单个线程,则不存在从一个线程到另一个线程修改非线程安全对象之间的并发性问题。在使用EDT以外的线程时,Swing代码不中断的情况在您的经验中可能很少见,但也有可能发生。
这种通过使用同一个线程修改和查询一组对象的状态来消除线程问题的做法称为线程限制。这是一个棘手的实践,因为它要求这些对象的用户在他们自己的应用程序代码中保持实践(例如当您在Swing中使用invokeLater时)。