解释以下代码的作用?

2022-09-03 09:37:58
java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        new NewJFrame().setVisible(true);
    }
});

请告诉我上面的代码实际上做了什么。我正在寻找逐行解释。特别是第一行,告诉我为什么我们使用它,以及在什么情况下我们必须使用它。


答案 1

在此示例中,您将看到一个从 Runnable 派生的 anyonmous 类。此匿名类重写可运行的接口的 run 方法。然后,此匿名类被实例化并传递给 EventQueue.invokeLater 方法,该方法是一个静态方法。此方法将对象追加到...井。。。事件队列。在EvenQueue中有许多事件,如键盘事件或鼠标事件或其他事件。有一个线程继续轮询此队列中的数据。一旦该线程到达在此处实例化的匿名类,它将执行run()方法,该方法将实例化类NewJFrame的对象并将其设置为可见。

这样做的要点是,新的 JFrame().setVisible(true) 部分不是在主线程中执行的,而是在事件调度线程中执行的。在 Swing 中,必须执行在事件调度线程中修改用户界面的所有代码。


答案 2

单线程模型和 EDT

大多数现代 UI 库都采用 .这意味着,对 UI 组件的所有操作都必须在同一单个线程上完成。为什么?这是因为允许从多个线程更新UI组件将导致混乱,因为大多数Swing对象方法都不是“线程安全的”。为了简单、高效和稳健,采用单线程模型。single-thread-model

在 Swing 中,为 提供服务的线程称为事件调度线程,即 EDT。它不是由 Swing 提供的。它由抽象窗口工具包(即AWT)提供。single-thread-model

工作线程与 UI 线程

一个不平凡的 GUI 应用程序通常具有许多线程。在现代 GUI 应用程序中,可能有许多工作线程来执行脏工作,但只有一个 UI 线程(Swing 将其称为 EDT)来更新 GUI。工作线程通常需要在 GUI 中反映其工作进度,因此它们需要与 UI 线程就此进行通信。那么这种沟通是如何发生的呢?

java.awt.EventQueue

通信通过消息队列模型进行。是全局提供事件队列的类。此全局事件队列用作到 EDT 的通信通道。EDT 从此事件队列中选取消息并相应地更新 UI 组件。如果程序的其他某个部分想要操作 UI,则该部分代码应调用消息或将消息排队到 EventQueue 中。EDT 将处理事件队列中的所有挂起消息,并最终到达该消息。java.awt.EventQueueEventQueue.invokeLater()EventQueue.invokeAndWait()

主线程

您的代码片段通常驻留在线程中,该线程可以被视为某种类型。只是它不是通过将消息发布到事件队列来更新 GUI,而是启动 GUI。无论如何,启蒙也可以被视为一种工作main()mainworker thread

启动 GUI 后,主线程将退出,EDT 将阻止进程退出。

另一个很好的解释:

Java 事件分派线程说明

一篇有趣的文章:多线程工具包,一个失败的梦想?


推荐