经过多年的 Java 编程,我总是习惯于创建这样的
main()
方法:
public static void main(String[] args)
{
runProgram();
}
但是最近我从网上研究了一些代码,有时看到这个而不是上面通常使用的
main()
:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
runProgram();
}
});
}
我只是想知道:
main()
方式?当我尝试时,我看不出有什么不同。感谢您阅读我的文章和您的回答。
因为VM启动的线程“main”不是事件调度线程。
API 中的一些 Swing 组件不是线程安全的,这意味着它们可能会导致一些问题,例如死锁,因此最好使用 Swing 提供的事件调度程序线程而不是从主线程或任何其他线程来创建和更新此类 Swing 组件。从 main 创建的其他线程。
虽然上面的答案都是正确的,但我相信他们缺乏正确的解释。
是的,与 Swing 交互的所有事情(创建 UI、更新 UI、添加新组件或布局等)都应该始终在 AWT 事件调度线程上完成(有关该主题的更多信息,请参阅 this post)。
SwingUtilities.invokeLater()
将您的代码放置在事件派发线程 (EDT) 的 FIFO 队列中,因此只要它完成了正在执行的其他任务,就会从 EDT 执行它。
话虽如此,EDT 应该专门用于运行快速执行的 Swing 相关任务(如果阻止 EDT,则会阻止整个 UI)。
如果您不使用 Swing/AWT(例如 JavaFX 应用程序或终端应用程序),则在 main 方法上使用
SwingUtilities.invokeLater()
是没有意义的。
如果您想要执行一些与 Swing 完全无关但需要启动 Swing 的任务(例如,在类似 MVC 的应用程序中启动模型和控制器),您可以从 EDT 或主线程(有关此主题的讨论请参阅这篇文章)。