Java 为什么在main方法中使用SwingUtilities.invokeLater?

Java 为什么在main方法中使用SwingUtilities.invokeLater?,java,swing,main,swingutilities,invokelater,Java,Swing,Main,Swingutilities,Invokelater,经过多年的Java编程,我总是创建我的main()方法,如下所示: public static void main(String[] args) { runProgram(); } 但最近我研究了一些来自Web的代码,有时看到了这一点,而不是上面通常使用的main() public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public

经过多年的Java编程,我总是创建我的
main()
方法,如下所示:

public static void main(String[] args) 
{
    runProgram();
}
但最近我研究了一些来自Web的代码,有时看到了这一点,而不是上面通常使用的
main()

public static void main(String[] args) 
{
    SwingUtilities.invokeLater(new Runnable() 
    {
        public void run() 
        {
            runProgram();
        }
    });
}
我只是想知道:

  • 为什么要使用此方法而不是通常的
    main()
    方法?我试一试,看不出有什么不同
  • 这两种方式有什么区别

感谢您阅读我和您的答案。

文档解释了原因。从

为什么初始线程不直接创建GUI本身?因为几乎所有创建Swing组件或与之交互的代码都必须在事件分派线程上运行

来自

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


由于VM启动的线程“main”不是事件调度线程

API中的一些Swing组件不是线程安全的,这意味着它们可能会导致一些问题,如死锁,因此,最好使用swing提供的事件调度程序线程来创建和更新此类swing组件,而不是从主线程或从主线程创建的任何其他线程来创建和更新这些组件。

虽然上面的答案都是正确的,但我相信它们缺乏正确的解释

是的,与Swing交互的所有操作(创建UI、更新UI、添加新组件或布局等)都应该始终在AWT事件调度线程上完成(有关该主题的更多信息,请参阅)

SwingUtilities.invokeLater()
将您的代码放入事件调度线程(EDT)的FIFO队列中,因此每当它完成正在执行的其他任务时,它都将从EDT执行


话虽如此,EDT应专门用于运行快速执行的Swing相关任务(如果阻止EDT,则阻止整个UI)

如果您不使用Swing/AWT(例如JavaFX应用程序或终端应用程序),那么在main方法上使用
SwingUtilities.invokeLater()
是没有意义的


如果您想执行一些与Swing完全无关但需要启动Swing的任务(例如,在类似MVC的应用程序中启动模型和控制器),您可以从EDT或主线程(有关此主题的讨论,请参阅)。

我明白了,非常有趣。感谢您的链接,并强调了要点。如果main直接调用runProgram(),有没有一个小的明确的例子说明会出现什么问题?据我所知,这里显示的链接参考和摘录似乎都不能回答这个问题。