Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 为什么Swing线程模型被认为是错误的,应该如何?_Java_Multithreading_Swing - Fatal编程技术网

Java 为什么Swing线程模型被认为是错误的,应该如何?

Java 为什么Swing线程模型被认为是错误的,应该如何?,java,multithreading,swing,Java,Multithreading,Swing,我多次听说Java Swing线程模型是错误的。我不完全理解为什么,我知道这个问题与您可以从主UI线程以外的另一个线程中绘制可绘制的有关。我知道有一些实用程序功能,比如SwingUtilities.invokeAndWait和SwingUtilities.invokeLater,可以让您在Runnable中进行绘制,然后由事件调度程序线程运行。我想这样可以确保绘画是同步完成的,并且不会让缓冲区处于不一致的状态 我的问题是:“好”的UI工具包是如何工作的?采取了哪些解决办法 Swing有一个线程,

我多次听说Java Swing线程模型是错误的。我不完全理解为什么,我知道这个问题与您可以从主UI线程以外的另一个线程中绘制
可绘制的
有关。我知道有一些实用程序功能,比如
SwingUtilities.invokeAndWait
SwingUtilities.invokeLater
,可以让您在
Runnable
中进行绘制,然后由事件调度程序线程运行。我想这样可以确保绘画是同步完成的,并且不会让缓冲区处于不一致的状态


我的问题是:“好”的UI工具包是如何工作的?采取了哪些解决办法

Swing有一个线程,负责让用户与应用程序的图形部分进行交互。如果您仅对用户启动的事件执行快速任务,则应用程序将始终具有响应性

如果从用户启动的事件执行长时间运行的任务,而不使用单独的线程运行该任务,则可能会出现问题-问题是,当任务运行时,应用程序将冻结。不会发生重绘,用户将无法完全与之交互,看起来应用程序只是将自己锁定在外面

如果您在单独的线程中运行任务(例如,您正在下载一个页面,并且希望通知用户下载已完成),那么您不能直接从该任务更新Swing,而是必须使用您在问题中提到的帮助器方法之一


创建这些任务是一个劳动强度更大的过程,因此应用程序始终具有响应性。但是,如果您运行的某项任务需要很长时间(下载文件就是一个很好的例子),则即使在执行任务时,应用程序也会继续具有响应性,您甚至可以让用户取消任务,只要任务本身允许就行。您可以使用模式对话框来阻止用户在执行任务时执行任何其他操作(如果您希望这样做),或者使用显示旋转轮或类似内容的进度对话框。但我想重要的是不要让用户认为应用程序只是无缘无故地“冻结”了。

当前显示技术的实现方式是,在屏幕上绘制像素总是串行的。你需要每秒生成大约30个图像,然后一个接一个地绘制它们

所以这幅画没有必要是多线程的,因为你仍然需要在背景中进行一些同步。这实际上就是Swing所做的-它使用一个名为Event Dispatch thread的特殊线程来安排在下一个映像之前发生的所有更改

因此,从技术上讲,如果使用EDT提交更改,Swing是线程安全的。这就是
invokeLater()
invokeAndWait()
方法的用途。他们向EDT提交更改

如果您不使用EDT并提交一些长期运行的更改,例如在按下按钮后计算一些值,您可以看到应用程序变得无响应,而不是重新绘制自身。因为EDT正忙着为您计算,没有时间安排重画和其他活动。

Brian Goetz

9.1为什么GUI是单线程的?

…在过去,GUI应用程序是单线程和GUI事件 从“主事件循环”处理。现代GUI框架使用 模型只是略有不同:它们创建了一个专用事件 用于处理GUI事件的调度线程(EDT)。单线程GUI 框架不是Java独有的;Qt,下一步,MacOS Cocoa,X Windows和许多其他窗口也是单线程的。这不是给你的 缺乏尝试;已经有很多人尝试编写多线程 GUI框架,但由于种族问题的持续存在 条件和僵局,他们最终都达成了一致 单线程事件队列模型,其中一个专用线程获取 事件离开队列并将其分派到应用程序定义的事件 处理程序

对于SWT:

SWT实现了一个单线程用户界面模型,通常称为单元线程。在这个模型中,只有用户界面线程可以调用用户界面操作。这条规定是严格执行的。如果尝试从用户界面线程外部访问SWT对象,则会出现SWTException(“无效线程访问”)

所以SWT也是单线程的。但是它需要额外的步骤来禁止在UI线程之外对UI进行任何更改。考虑在Swing中的另一种选择,即从其他地方修改UI,但会产生迟早的意外结果,这会使新手程序员感到困惑,后者将了解Swing是单线程的“硬”方式。 此外,如果您的设计不清楚,您可能会遇到这样的情况:您认为自己的思路正确,但实际上并非如此。您也可能无法可靠地判断哪些线程将访问特定的代码段,但无论如何,您自己的代码中可能存在严重的设计问题


除此之外,我无法想象为什么Swing的线程模型会被认为是“错误的”的其他原因。

请投赞成票。我认为你的问题很好。也许你可以把你在哪里听到的链接起来?你有这篇论文的参考资料吗?我从没听说过。Swing的线程模型非常简单:它被称为单线程。如果你不理解你“听到”的内容,你也不能指望没听过的人理解。也许你应该更努力一点。Swing是单线程的。Windows也是如此。OS/2演示管理器也是如此。X视窗系统也是如此,因为“错误”没有一个客观的定义,也没有任何具体的投诉,更不用说