Java 解释以下代码的作用?

Java 解释以下代码的作用?,java,swing,concurrency,runnable,Java,Swing,Concurrency,Runnable,请告诉我上面的代码实际上是做什么的。我正在寻找逐行解释。特别是第一行,请告诉我为什么要使用它,以及在什么情况下必须使用它。在本例中,您会看到一个从Runnable派生的anyonmous类。此匿名类重写接口runnable的run方法。然后实例化该匿名类并将其传递给EventQueue.invokeLater方法,该方法是一个静态方法。此方法将对象附加到。。。好。。。事件队列。队列中有许多事件,如键盘事件、鼠标事件或其他事件。有一个线程持续轮询此队列中的数据。一旦该线程到达此处实例化的匿名类,它

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

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


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

这是一个指示稍后执行的代码块(有时称为a)。内部类(
newrunnable(){…}
)本质上允许您传递将要运行的代码块。保证代码块将运行,但不保证何时运行。有时,立即运行某些代码是不安全的,而且自己执行多线程太冗长了。因此Java提供了这个实用方法来安全地运行代码。代码将很快运行,但必须在安全的情况下才能运行。

调用调用调用器将把指定的runnable放在队列上,以便稍后处理。也就是说,当
invokeLater
方法调用返回时,
run()

这类代码有两个典型的用例

  • 当前正在执行的代码在后台线程中运行。后台线程无法访问大多数swing API。请阅读更多信息了解原因。如果当前线程已经是UI线程,那么没有理由,可以安全地删除调用
  • 必须退出当前块(代码到达最后一个大括号)。这可能会导致资源被释放等等。这并不常见
  • 匿名类作为参数传递给
    invokeLater
    调用。它与此代码相同

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
    

    invokeLater()方法将可运行对象作为其参数。它将该对象发送到事件调度线程,该线程执行run()方法。这就是为什么run()方法执行Swing代码总是安全的


    -IvarD单线程模型和EDT

    大多数现代UI库采用
    单线程模型
    。这意味着,对UI组件的所有操作必须在同一个线程上完成。为什么?这是因为允许从多个线程更新UI组件将导致混乱。为了简单、高效和健壮,采用了单线程模型

    在Swing中,服务于
    单线程模型的线程称为,即EDT。它不是由Swing提供的。它由AWT提供,即AWT

    工作线程与UI线程

    一个非平凡的GUI应用程序通常有许多线程。在现代GUI应用程序中,可以有许多工作线程来执行脏活,但只有一个UI线程(Swing称之为EDT)来更新GUI。工作线程通常需要在GUI中反映他们的工作进度,所以他们需要与UI线程就此进行通信。那么这种交流是如何发生的呢

    java.awt.EventQueue

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

    主线程

    您的代码片段通常位于
    main()
    线程中,这里可以将
    main
    线程视为某种
    工作线程。只是它没有通过向EventQueue发送消息来更新GUI,而是启动GUI。无论如何,启蒙也可以被视为一种工作

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

    另一个很好的解释是:

    一篇有趣的文章:

    这是一个很好的解释。。告诉我为什么我们在这里使用runnable(),我想(新的JFrameCreator())会创建一个匿名类。这是否意味着当处理此线程时,run()会自动执行。如果我问的问题完全错了,我很抱歉。。我只想知道run()和(new JFrameCreator())……不,对不起,这不起作用。类JFrameCreator必须实现Runnable(只需编写类JFrameCreator实现Runnable)。和@Deepak:No,此示例中没有涉及匿名类。@yankee:只有当类JFrameCreator实现为可运行时,才会调用run()方法?或者,如果我们为JFrameCreator提供一个构造函数,并在该构造函数中调用setVisible(true)会怎么样??这行吗?@Deepak:是的,它不会调用run()方法。因为这段代码甚至不会编译。invokeLater()方法希望获得一个实现Runnable的对象。信息技术
    private void foo()
    {
      java.awt.EventQueue.invokeLater(new JFrameCreator());
    }
    private class JFrameCreator implements Runnable
    {
      public void run() {
        new NewJFrame().setVisible(true);
      }
    }