为什么我应该使用单独的线程在JAVA中显示GUI

时间:2012-10-01 03:10:42

标签: java swing runnable swingutilities invokelater

这个简单的问题让我很困惑。您可以通过设置框架“setVisible属性true来显示JAVA GUI应用程序。但在我在互联网上发现的几乎所有例子中,他们都使用一个单独的线程来做同样的事情。

他们做这样的事情,

SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        new Frame().setvisible(true);  //just take the idea of this line
    }
});

我发现这两种方法没有区别。但必须是一些特殊原因,这就是每个人都这样做的原因。

有人可以解释一下......谢谢!

6 个答案:

答案 0 :(得分:9)

以这种方式启动应用程序的主要原因是Swing组件不是线程安全的,因此您需要保证GUI将从哪个线程开始:名为{{1}的线程( EDT )。如果不这样做,你就无法确定它将从哪个线程开始,但正如几位评论员所指出的那样,主线程保证不是 EDT。

您应该只在EDT中创建,访问或修改UI组件。否则将导致意外行为(如果你很幸运)和/或脏污重绘。

我建议您熟悉一些资源:

您还可以阅读Why does my boilerplate Java desktop app JFrame use EventQueue.invokeLater in the main method?

<强>更新

这是我一直试图找到的blog:P

这基本上解释了为什么在开始之前将Event Dispatching Thread与EDT同步很重要,它还描述了有关原因的一些细节。

它还描述了为什么许多开发人员在启动他们的应用程序时犯了这个根本错误(基本上,我们被告知我们可以,但我们从未真正被允许......糟糕的我们)

答案 1 :(得分:3)

因为您在GUI上执行的每项修改都应在event dispatching thread上完成。这就是 AWT SWING 的工作方式。

这是因为重绘是在一个线程上执行的,通过使用invokeLater,你让该线程管理它,而没有由于缺乏Swing的线程安全性而发出的潜力。使用该语法,您可以委托在适当的线程上执行该指令,该线程是管理GUI元素的线程。

答案 2 :(得分:3)

Swing不是线程安全的,所有组件都需要在EDT中初始化。这样可以防止死锁等问题。

答案 3 :(得分:3)

Swing类不是线程安全的;他们的线程正确性只是因为它们上的所有操作都在同一个线程(事件调度线程或EDT)上执行。因此,每当您与Swing对象进行交互时,必须在EDT上 - 并且SwingUtilities.invokeLater是一种很好的方法。

如果没有那个调用,如果你刚从任何一个线程调用setVisible(true),你将没有任何线程安全性,Frame甚至可能看不到该方法的操作。更糟糕的是,Frame只能看到一些行为,打破内部假设和不变量,导致奇怪的行为,崩溃或死锁。

答案 4 :(得分:3)

几乎任何调用Swing方法的操作都必须在Swing Event Dispatch线程上运行。 invokeLater()是确保此不变量成立的方法。 详细了解此here

另请注意,大多数其他GUI工具包也是如此,例如.NET,MFC等中的表单。

答案 5 :(得分:1)

Java gui框架被设计为一个线程来强制执行线程安全:这种技术称为线程限制。任何gui操作,例如因此,组件创建,模型创建,事件发送等必须在事件调度线程(EDT)中执行。 您描述的方式是在EDT中排队操作的一种方法。