Java事件派遣线程说明

lin*_*ash 54 java swing awt event-dispatch-thread

我最近开始学习和探索Java中GUI编程的基础知识.

经过一段时间的编程后,我只完成了后端工作或工作,因此最接近用户界面的是命令控制台(我知道这令人尴尬).

我正在使用Swing,据我所知,这意味着我也使用AWT.

我的问题是基于这段代码:

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        new frame.setVisible(true);
    }
} );
Run Code Online (Sandbox Code Playgroud)

我一直在研究这一段时间,因为我想完全理解这种奇怪的代码和所遇到的术语"事件派发线程"多次.如果我错了,但正如我所理解的那样纠正我; 它与使用多个线程以及Java Swing如何解释这些线程有关.我也收集到上面的代码用于确保所有线程在创建窗口之前是"安全的",因此invokeLater?

我读过:

"你只能从Event-Dispatching Thread中调用对框架进行操作的方法"

并且只有在某些情况下才能调用main方法对框架进行操作的方法.

有人可以向我澄清一下Event-Dispatching Thread到底是什么吗?

它如何与多个执行线程相关,以及如何从main方法调用这些线程是不安全的?为什么我们需要这个invokeLater?

我们不能像其他任何对象一样创建窗口吗?

我在研究中遇到了一些障碍,因为我没有抓住这些关系和想法.

一个侧面说明,我喜欢将我的知识建立在深入理解的基础上,因为我相信这会带来最好的整体结果,并因此成为最好的计划.如果我深入了解某些东西是如何工作的,那么你可以有效地使用提示和调整,而不仅仅是将它们重新编入代码中,所以请不要害怕给我一些额外的深入解释并扩展我的知识.

谢谢.

luk*_*uke 60

EventDispatching线程是由AWT管理的特殊线程.基本上它是一个在无限循环处理事件中运行的线程.java.awt.EventQueue.invokeLater方法是一种提供将在事件队列上运行的代码的特殊方法.编写一个在多线程环境中安全的ui框架非常困难,因此AWT作者认为他们只允许在一个特殊线程上对GUI对象进行操作.所有事件处理程序都将在此线程上执行,所有修改gui的代码也应该在此线程上运行.

现在AWT通常不检查你是不是从另一个线程发出gui命令(C#的WPF框架确实这样做).因此可以编写大量代码并且对此非常不可知,并且不会遇到任何问题.但这可能会导致未定义的行为,因此最好的办法是始终确保gui代码在事件调度程序线程上运行.invokeLater提供了执行此操作的机制.

所以一个典型的例子就是你需要运行一个长时间运行的操作,比如下载一个文件.因此,您启动一​​个线程来执行此操作,然后在完成后,您将使用invokeLater更新UI.如果您没有使用invokeLater,而是直接更新了ui,则可能会出现竞争条件,并且可能会发生未定义的行为.

维基百科有更多信息:http://en.wikipedia.org/wiki/Event_dispatching_thread

另外,如果你很好奇为什么awt作者不只是在这里制作多线程工具包是一篇好文章:https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream

  • 在许多情况下,您可以保证已经在 EDT 上执行,例如事件处理程序(ActionListeners、ClickListeners),因此无需从那里使用 invokeLater。我认为 SwingWorker 只是一个具有与 EDT 交互的特殊机制的线程(可能通过 invokeLater)。所以如果合适,我肯定会使用它。 (2认同)
  • 您好,Java 博客文章的链接不再指向博客文章。您可以更新您的链接,或发布该帖子的某些存档版本的链接吗? (2认同)

mKo*_*bel 12

EventDispatchThread(EDT)是仅为Swing GUI和*Swing相关事件保留的特殊线程,例如创建/更改/更新Swing JComponents,更多用于此处此处的问题

所有输出到GUI的BackGround Tasks,都Runnable#Thread必须包装到invokeLater()中,从同步对象进入invokeAndWait();