Java事件派发线程讲解

发布于 2024-12-02 03:21:58 字数 933 浏览 7 评论 0原文

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

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

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

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

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

我已经研究了一段时间,因为我想完全理解这段奇怪的代码,并且多次遇到术语“事件调度线程”。如果我错了,请纠正我,但据我了解;它与使用多个线程以及 Java Swing 如何解释这些线程有关。我还收集到上面的代码用于确保所有线程在创建窗口之前都是“安全的”,因此调用Later?

我读过:

“您只能从事件调度线程调用对框架进行操作的方法”

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

有人可以向我解释一下事件调度线程到底是什么吗?

它与多个执行线程有何关系,以及为什么从主方法调用这些线程不安全?另外,为什么我们需要这个 invokeLater?

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

我在研究中遇到了一些障碍,因为我没有掌握这些关系和想法。

附带说明的是,我喜欢将我的知识建立在深入理解的基础上,因为我相信这会带来最好的整体结果,从而带来最好的项目。如果我深入了解某些东西是如何工作的,那么您可以有效地使用这些技巧和调整,而不是仅仅将它们重复到代码中,所以请不要害怕给我一些额外深入的解释并拓宽我的知识。

谢谢。

I've recently started learning and exploring the basics of GUI programming in Java.

Having been programming for a while I have only done backend work or work and as a result the closest I've gotten to user interfaces is the command console (embarrassing I know).

I'm using Swing and as far as I can gather that means by extension I am also using AWT.

My question is based on this piece of code:

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

I have been researching this for a while as I wanted to fully understand this strange piece of code and have come across the term 'Event-Dispatching Thread' multiple times. Correct me if I'm wrong but as I understand it; it has to do with using multiple threads and how Java Swing interprets those threads. I gather as well that the above code is used to make sure all the threads are 'safe' before it creates the window, hence the invokeLater?

I have read that:

"You can only call methods that operate on the frame from the Event-Dispatching Thread"

and that only under certain circumstances can you call methods that operate on the frame from the main method.

Can somebody please clarify to me what exactly the Event-Dispatching Thread is?

How it relates to multiple threads of execution and how those threads are not safe to be called from the main method? Also why do we need this invokeLater?

Can we not just create the window as any other object?

I've hit a bit of a road block in my research as I'm not grasping these relations and ideas.

A side note is that I like to base my knowledge on in-depth understanding as I believe this leads to the best overall outcome and as a result the best programs. If I understand in-depth how something works then you can use the tips and tweaks effectively rather than just parroting them back in to code, so please don't be afraid to give me some extra in-depth explanations and broaden my knowledge.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不喜欢何必死缠烂打 2024-12-09 03:21:58

事件调度线程是一个特殊的线程,由AWT。基本上,它是一个在无限循环中运行的线程,处理事件。

java.awt.EventQueue.invokeLaterjavax.swing.SwingUtilities.invokeLater 方法是提供将在事件队列上运行的代码的一种方法。编写在多线程环境中安全的 UI 框架非常困难,因此 AWT 作者决定只允许在单个特殊线程上发生对 GUI 对象的操作。所有事件处理程序都将在此线程上执行,所有修改 GUI 的代码也应在此线程上运行。

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

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

维基百科有更多信息

另外,如果您好奇为什么 AWT 作者不只是制作多线程工具包,

The event dispatch thread is a special thread that is managed by AWT. Basically, it is a thread that runs in an infinite loop, processing events.

The java.awt.EventQueue.invokeLater and javax.swing.SwingUtilities.invokeLater methods are a way to provide code that will run on the event queue. Writing a UI framework that is safe in a multithreading environment is very difficult so the AWT authors decided that they would only allow operations on GUI objects to occur on a single special thread. All event handlers will execute on this thread and all code that modifies the GUI should also operate on this thread.

Now AWT does not usually check that you are not issuing GUI commands from another thread (The WPF framework for C# does do this), meaning it's possible to write a lot of code and be pretty much agnostic to this and not run into any problems. But this can lead to undefined behavior, so the best thing to do, is to always ensure that GUI code runs on the event dispatch thread. invokeLater provides a mechanism to do this.

A classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then, when it is completed, you use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the UI directly, you might have a race condition and undefined behavior could occur.

Wikipedia has more information

Also, if you are curious why the AWT authors don't just make the toolkit multithreaded, here is a good article.

葬シ愛 2024-12-09 03:21:58

EventDispatchThread (EDT) 是仅为 Swing GUI 和 *Swing 相关事件保留的特殊线程,例如 create/change/update Swing JComponents,更多询问问题 此处此处

所有从后台任务到GUI的输出, Runnable#Thread 必须包装到 invokeLater( ),从同步对象到 invokeAndWait();

EventDispatchThread (EDT) is special thread reserved only for Swing GUI and *Swing's related events e.g. create/change/update Swing JComponents, more for asked questions here and here

all output to the GUI from BackGround Tasks, Runnable#Thread must be wrapped into invokeLater(), from synchronized Objects into invokeAndWait();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文