【问题标题】:what is SwingUtilities.invokeLater(new Runnable()) [duplicate]什么是 SwingUtilities.invokeLater(new Runnable()) [重复]
【发布时间】:2014-04-04 10:15:34
【问题描述】:

谁能用简单的话解释一下这段代码:

SwingUtilities.invokeLater(
    new Runnable(){
        public void run(){
            chatWindow.append(text);
        }
    });
}

拜托,谁能给我详细的解释。

【问题讨论】:

    标签: java swing


    【解决方案1】:

    您正在创建Runnable 接口的匿名实现的实例,并将其传递给invokeLater,后者会将其放入队列中。另一个线程,Event Dispatch Thread,将 Runnables 从该队列中弹出并调用它们的run 方法。 (请注意,这确实是一个简单化的解释,并不100%符合现实。

    就你作为程序员感兴趣的效果而言,这使得下面的代码行:

    chatWindow.append(text);
    

    不是在当前线程上执行,而是在事件调度线程 (EDT) 上执行。如果您尝试在当前线程上执行它,则会导致未定义的行为,因为 Swing 不是线程安全的,并且所有 GUI 操作都必须在提到的 EDT 上发生。

    【讨论】:

    • 谢谢老兄!很好的解释
    • 您必须通过 Event Dispatch Thread 将文本附加到 chatWindow,因为 Swing 在单线程模型上工作。所有与 UI 相关的更新都应该通过 Event Dispatch Thread 来完成。
    【解决方案2】:

    这只是将一个任务添加到 Java 线程的任务队列中,该线程负责整个应用程序的呈现和事件。

    注意:这个线程叫做EDT(事件调度线程)。

    【讨论】:

      【解决方案3】:

      这是一种将一定数量的指令传递给 AWT 事件调度线程 (EDT) 的方法。这是必需的,因为从其他线程对与 AWT 相关的事物(如 JFrame 及其所有子项)进行操作是不好的做法。你最好把它交给 EDT,让它在适当的时候处理它。

      代码本身使用实现 Runnable 的匿名类,以便让您指定要在 EDT 上执行的内容。 Runnable 接口要求您实现run() 方法。然后 EDT 会在需要时调用您的类对象 run()

      【讨论】:

        【解决方案4】:

        答案:http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater%28java.lang.Runnable%29

        基本上,它会在所有 AWT 事件被消耗后立即启动内联 Runnable 对象的 run() 方法中的代码。

        【讨论】:

        • 它是否在新线程中运行
        【解决方案5】:

        Runnable 是 Java 中的一个接口,表示定义运行方法的类型。实现 Runnable 接口的类必须为其提供实现。 Thread 是众所周知的 Runnable。

        来自docs

        导致 doRun.run() 在 AWT 事件上异步执行 调度线程。这将在所有待处理的 AWT 事件完成后发生 被处理。应用程序线程时应该使用此方法 需要更新 GUI。在以下示例中,invokeLater 调用 在事件分派时将 Runnable 对象 doHelloWorld 排队 线程,然后打印一条消息。

        如果从事件调度线程调用 invokeLater -- for 例如,来自 JButton 的 ActionListener -- doRun.run() 仍将 被推迟到所有待处理的事件都处理完。

        【讨论】:

        • 我很困惑它是在新线程中运行还是在同一个线程中运行。
        【解决方案6】:

        虽然这些链接上很少有好的答案和解释,但我仍然在添加一些细节:

        Should we use EventQueue.invokeLater for any GUI update in a Java desktop application?

        http://www.javamex.com/tutorials/threads/invokelater.shtml

        Swing 事件处理代码在称为事件调度线程 (EDT) 的特殊线程上运行。大多数调用 Swing 方法的代码也在这个线程上运行。这是必要的,因为大多数 Swing 对象方法都不是线程安全的。所有与 GUI 相关的任务,应该对 GUI 进行任何更新,而绘制过程必须在 EDT 上进行,这涉及将请求包装在一个事件中并将其处理到 EventQueue 中。然后事件从同一个队列中一个一个地分派,按照它们排队的顺序,先入先出。也就是说,如果事件 A 在事件 B 之前入队到 EventQueue,那么事件 B 将不会在事件 A 之前分派。

        SwingUtilities 类有两个有用的函数来帮助完成 GUI 渲染任务:

        1) invokeLater(Runnable):导致 doRun.run() 在 AWT 事件调度线程 (EDT) 上异步执行。这将在处理完所有未决 AWT 事件后发生,如上所述。

        2) invokeAndWait(Runnable):它与invokeLater具有相同的功能,但它与invokeLater的不同之处在于: --> invokeAndWait 等待它给 EDT 的任务完成,然后返回。 --> 它阻塞(等待)当前(即,它通过同步锁发送到等待状态来调用线程继续执行。 --> 一旦这个函数发布的事件请求在EDT中被调度并且这个函数的调用者线程可以继续,它将释放锁。

        【讨论】:

          猜你喜欢
          • 2012-08-18
          • 2011-09-27
          • 2014-07-12
          • 1970-01-01
          • 2015-11-13
          • 1970-01-01
          • 2019-06-01
          • 2018-03-02
          • 1970-01-01
          相关资源
          最近更新 更多