Java中的主线程与UI线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的主线程与UI线程相关的知识,希望对你有一定的参考价值。

在这里作为答案给出的许多Swing片段中,从SwingUtilities#invokeLater方法调用main

public class MyOneClassUiApp {

    private constructUi() {
        // Some Ui related Code
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MyOneClassUiApp().constructUi();
            }
        });
    }
}

但根据Threads and Swing article,从主线程构造UI是安全的:

一些方法是线程安全的:在Swing API文档中,线程安全的方法用这个文本标记:

虽然大多数Swing方法都不是,但这种方法是线程安全的。

应用程序的GUI通常可以构造并显示在主线程中:只要没有实现组件(Swing或其他),以下典型代码是安全的:

public class MyApplication {
public static void main(String[] args) {
   JFrame f = new JFrame("Labels");
   // Add components to 
   // the frame here... 
   f.pack(); 
   f.show(); 
   // Don't do any more GUI work here... 
   } 
}

那么,是否有一个真正的(线程安全)理由通过SwingUtilities#invokeLater在main中构建UI,或者这只是一种习惯,要记住在其他情况下这样做吗?

答案

“Swing单线程规则:Swing组件和模型应仅从事件派发线程创建,修改和查询。” - Java Concurrency in Practice,还讨论了herehere。如果您不遵循此规则,则无法可靠地构造,修改或查询可能假定您遵循该规则的任何组件或模型。程序似乎可以正常工作,但只能在不同的环境中神秘地失败。由于违规行为可能不明确,请使用here提及的方法之一验证正确的使用方法。

另一答案

在main方法中创建Swing UI是安全的,因为在设置UI之前如何显示其他组件?只要你没有在屏幕上抛出一些东西你就没事了。换句话说,这会很糟糕:

public class MyApplication
{ 
  public static void main(String[] args)
  { 
    JFrame f = new JFrame("Labels"); 
    // Add components to  
    // the frame here...  
    f.pack();  
    f.show();  

    // now make another frame:
    JFrame f2 = new JFrame("Labels2"); 
    // Add components to the 2nd frame here...  
    f2.pack();  
    f2.show();  
  }  
}

如果您执行了上述操作,那么您将启动并运行JFrame f,然后您将从事件调度线程(EDT)中添加Swing UI组件。 invokeLater在EDT上运行代码 - 如果你想要额外的安心,使用它也不会有害。

另一答案

我认为使用SwingUtiltities.invokeLater()只是一种异步执行某些代码的简单方法。有时某些应用程序需要它:例如,您可以同时创建2个单独的窗口。而已。

以上是关于Java中的主线程与UI线程的主要内容,如果未能解决你的问题,请参考以下文章

当 Cocoa 应用程序中的主线程被阻塞时,UI 不会更新

应用程序可能在 Andriod 中的主线程(Firebase 数据库)上做了太多工作

在主线程上处理大型全局对象时如何不阻止来自工作线程的主 UI 线程

11.1-全栈Java笔记:多线程技术的基本概念

Java多线程与并发库高级应用-工具类介绍

Java多线程与并发库高级应用-工具类介绍