【问题标题】:Why should I use a separate thread to show a GUI in JAVA为什么我应该使用单独的线程在 JAVA 中显示 GUI
【发布时间】:2012-09-21 22:30:43
【问题描述】:

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

他们会这样做,

SwingUtilities.invokeLater(new Runnable() {

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

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

谁能解释一下..谢谢!

【问题讨论】:

    标签: java swing runnable swingutilities invokelater


    【解决方案1】:

    以这种方式启动您的应用程序的主要原因是 Swing 组件不是线程安全的,因此您需要保证您的 GUI 将从哪个线程开始:称为 Event Dispatching Thread 的线程( 美国东部时间)。如果不这样做,您无法确定它将从哪个线程开始,但正如一些评论员所指出的,主线程保证不是 EDT。

    您只能在 EDT 中创建、访问或修改 UI 组件。否则会导致意外行为(如果幸运的话)和/或脏重绘。

    我建议您熟悉一些资源:

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

    更新

    这是我一直在寻找的blog:P

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

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

    【讨论】:

    • 这不是必须使用 EDT 的原因。
    • 你是怎么知道的?你没有保留任何参考?顺便说一句,我为什么要知道这一点(我的意思是一个简单的应用程序).​​.....
    • @LanguagesNamedAfterCofee 什么意思?
    • @Anubis 保留了对什么的引用?包装调用的主要原因是确保您的 UI 代码在 EDT 中执行。
    • @Anubis 抱歉,需要时间来寻找愚蠢的东西——我的错:P
    【解决方案2】:

    因为您在 GUI 上所做的每一次修改都应该在 event dispatching thread 上完成。这就是 AWTSWING 的工作原理。

    这是因为重绘是在单个线程上执行的,通过使用invokeLater,您可以让该线程管理它,而不会因 Swing 缺乏线程安全性而产生潜在问题。使用该语法,您可以将该指令委托给在适当的线程上执行,该线程是管理 GUI 元素的线程。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          几乎所有调用 Swing 方法的操作都必须在 Swing Event Dispatch 线程上运行。 invokeLater() 是确保此不变量成立的方法。 阅读更多关于此here 的信息。

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-10-31
              • 1970-01-01
              • 2011-05-06
              • 1970-01-01
              • 2014-01-30
              • 1970-01-01
              • 2012-09-08
              • 1970-01-01
              相关资源
              最近更新 更多