为什么要使用swingutility ?在主方法中调用



经过多年的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()方式?我试了一下,没发现有什么不同。
  • 这两种方式有什么区别?

谢谢你的阅读和你的回答。

文档解释了原因。来自Initial Threads

为什么初始线程不直接创建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或主线程中完成(参见这篇文章关于这个主题的讨论)。

相关内容

  • 没有找到相关文章

最新更新