Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么是事件调度线程?_Java_User Interface_Multithreading - Fatal编程技术网

Java 什么是事件调度线程?

Java 什么是事件调度线程?,java,user-interface,multithreading,Java,User Interface,Multithreading,我知道“线程”是什么意思,如果我把事件调度线程(EDT)理解为 “只是一根线”,它解释了很多,但显然,它并不能解释一切 我不明白这条线有什么特别之处。例如,我不明白为什么我们应该在EDT中启动GUI?为什么“主”线程是GUI的基础?好吧,如果我们只是不想占据主线程,为什么我们不能在“另一个线程”中启动GUI,为什么它应该是一些称为EDT的“特殊”线程 那么我不明白为什么我们不能像其他线程一样启动EDT?为什么我们应该使用一些特殊的工具(称为invokeLater)。和其他线程不同的是,为什么GU

我知道“线程”是什么意思,如果我把事件调度线程(EDT)理解为 “只是一根线”,它解释了很多,但显然,它并不能解释一切

我不明白这条线有什么特别之处。例如,我不明白为什么我们应该在EDT中启动GUI?为什么“主”线程是GUI的基础?好吧,如果我们只是不想占据主线程,为什么我们不能在“另一个线程”中启动GUI,为什么它应该是一些称为EDT的“特殊”线程

那么我不明白为什么我们不能像其他线程一样启动EDT?为什么我们应该使用一些特殊的工具(称为
invokeLater
)。和其他线程不同的是,为什么GUI不能立即启动。我们应该等到它准备好接受我们的工作。是否因为EDT可能同时执行多个任务

如果你决定回答这个问题,请你使用一个非常简单的术语,否则,我恐怕无法理解答案

添加:

我一直认为每个线程有一个“任务”。因此,在每个线程中,我们执行预定义的命令序列。但在我看来,在调度线程的事件中,我们可以执行一些任务。嗯,它们不是同时执行的(线程在不同的任务之间切换,但在一个线程中仍然有多个任务)。是这样吗?例如,EDT中有一个显示主窗口的线程,除此之外,我们还向EDT发送了另一个任务,该任务应更新其中一个窗口组件,EDT将在准备就绪时执行此新任务。EDT在这方面与其他线程不同吗

What is the EDT?
这是一种针对Swing API存在的大量并发问题的黑客解决方法;)

说真的,很多Swing组件都不是“线程安全的”(一些著名的程序员甚至称Swing为“线程不安全的”)。通过拥有一个唯一的线程,所有的更新都是针对该线程的组件进行的,您就避免了许多潜在的并发问题。除此之外,还保证它将运行您使用invokeLater按顺序传递的Runnable

请注意,这不仅仅是因为您回避了并发性问题:您必须遵守Sun关于在EDT上必须做什么和不能做什么的指导原则,否则您的应用程序将出现严重问题

另一个好处是,一些Swing组件倾向于抛出不需要的异常,当这种情况发生时,它们会自动处理,不会使EDT崩溃(如果您真的设法杀死EDT,它会自动重启)

换句话说:你不必处理所有损坏的Swing组件和它们自己抛出的异常:EDT正在处理这些(只要看看Sun的bug游行中无数抛出异常的Swing bug就知道了,这很吸引人……但大多数应用程序都能正常工作)


此外,通过只执行EDT中的强制操作,您的应用程序的GUI可以保持“响应”,即使很难,也可能会有任务在后台运行。

需要记住的重要一点是Swing类不是线程安全的。这意味着您应该始终从同一个线程调用Swing方法,否则可能会出现奇怪或未定义的行为

所以解决方案是:只从单个线程调用Swing方法。这是EDT线程——除了指定从中调用swing方法的线程之外,它在任何方面都不特殊


现在您可能会问为什么Swing方法不是线程安全的?在几次失败的尝试之后,GUI工具包设计者发现设计线程安全的GUI工具包本质上是不可能的。事件经常以相反的方向传递(从下到上的输入事件,从上到下的应用程序事件),这总是导致死锁。这就是事实

事件调度线程是处理所有GUI事件并管理Swing GUI的线程。如果您的程序中有任何GUI,它将在Swing代码的某个地方启动。之所以在幕后进行,是因为简单——您不必费心自己启动和管理额外的线程

关于必须使用
invokeLater()
更新GUI的事实,这是因为并发性问题。GUI只能从一个线程修改,因为Swing不是线程安全的(值得注意的是,大多数工具包都不是线程安全的,有一个例子给出了一些原因)。这就是为什么您必须提交所有GUI更新才能在EDT上运行

您可以阅读更多关于Swing中并发性和中事件调度线程的内容。另外,如果你想看看如何以不同的方式完成这项工作,你可能想看看。在SWT中,您必须自己管理EDT

我一直以为我们有一个 每个线程的“任务”。所以,在每一个线程中 我们执行一个预定义的 命令。但在我看来 事件调度线程,我们可以 有严重的任务。嗯,他们不是 同时执行(线程 在不同的任务之间切换,但 一个任务中仍然有几个任务 螺纹)。是这样吗?例如 EDT中有一个线程 显示主窗口,然后单击 除此之外,我们还向 EDT应更新的另一个任务 窗口组件和EDT之一 将在任何时候执行此新任务 准备好了。EDT和其他的有什么不同吗 是这样的吗

What is the EDT?
不,EDT与其他线程没有本质区别。而且“任务”不是一个好词,因为它可能与操作系统级进程(通常也称为任务)混淆。最好使用
Runnable
,该接口用于通过
invokeLater()将代码提供给EDT执行

EDT基本上连接到一个它必须做的事情队列。当用户单击一个按钮时