为什么大多数 UI 框架都是单线程的?
例如,Java Swing 和 Android UI 都使用单线程模型,其中单个 UI 线程负责更新所有 UI。是什么让框架设计者选择一种线程模型而不是另一种?
多线程 UI 模型是否有可能为您带来更高的性能,尽管代价是更加复杂?我意识到后者是一件大事,因为与线程相关的错误是令人讨厌的,但我想知道除了简单性之外,单线程模型是否还有其他优点?
For example, Java Swing and Android UI both use a single threaded model where a single UI thread is responsible for updating all the UI. What made the framework designers chose one thread model over the other?
Wouldn't multiple threaded UI model potentially give you more performance albeit at the cost of more complexity? I realize that the latter is a big deal because thread related bugs are nasty but I am wondering if there are any other advantages to single-threaded model other than simplicity?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
来自马口:
(阅读整篇文章,它非常详细地解释了这一决定,并指出完全相同的问题和最终转向单线程模型的情况甚至早在 Xerox PARC 就曾发生过——在那里,几乎所有我们认为现代 CS 领域的前沿技术都曾在 Xerox PARC 中出现过。 30年前发明)
绝对不是,因为绘制 GUI 和处理用户操作(这是 UI 线程需要做的所有事情)不会成为任何正常 2D 应用程序的瓶颈。
From the horse's mouth:
(Read the whole article, it explains the decision in great detail and states that the exact same problems and eventual move to a single-threaded model had even occured earlier at Xerox PARC - the place where almost everything we consider bleeding edge modern in CS was invented 30 years ago)
Absolutely not, because drawing the GUI and processing user actions (which is everything the UI thread needs to do) is not going to be the bottleneck in any sane 2D application.
在大多数情况下并非如此,而且在绝大多数情况下,增加的复杂性弊大于利。您还必须认识到 UI 框架也必须处理底层操作系统模型。当然,它可以围绕模型工作并将其从程序员那里抽象出来,但在这种情况下根本不值得。
由多个线程临时更新 UI 引起的错误数量将远远超过大多数情况下毫无意义的性能提升(如果甚至有提升,由于锁定和同步,线程会带来其自身的相关开销,您可能会实际上很多时候只是让性能变得更糟)。
在这种情况下,最好仅在需要时显式使用多个线程。大多数时候,在 UI 中,您希望所有内容都在一个线程上,而使用多个线程则不会获得太多好处。 UI 交互几乎从来都不是瓶颈。
Not in most cases, and that added complexity would do more harm than good the vast majority of the time. You also have to realize that the UI framework must deal with the underlying OS model as well. Sure, it could work around the model and abstract that away from the programmer, but it's simply not worth it in this case.
The amount of bugs caused by multiple threads updating the UI ad hoc would far outweigh what would be for the most part meaningless performance gains (if there were even gains, threading comes with an associated overhead of its own due to locking and synchronization, you may actually just be making the performance worse a lot of the time).
In this case it's better to use multiple threads explicitly and only when needed. Most of the time in a UI you want everything on one thread and you don't gain much if anything by using multiple threads. UI interactions are almost never a bottleneck.
不,可能不会。至少当您尝试在 CPU 上运行线程时不会。 GPU 上已经存在大量各种形式的并行处理。不是简单的 GUI 工作,而是花哨的 3D(阴影、反射等)
No, probably not. At least not when you try to run the threads on the CPU. On the GPU there is already a lot of parallel processing in various forms. Not as much for the simple GUI work, but for fancy 3D (shading, reflections etc.)
我认为这都是为了防止死锁。
Swing 的组件不被认为是线程安全的,并且由于此事件分派器线程,它们不必是线程安全的。如果 UI 是多线程的,则整个应用程序将必须依赖每个组件以线程安全的方式运行,如果有任何组件不这样做,则可能会在模糊的情况下出现死锁。
所以,它更安全。
不仅如此,Windows Forms(和.Net)、GTK、Motif 和其他各种应用程序也选择了相同的设计。我想知道 Java 是否会因为与其交互的底层操作系统 API 而被迫做出这个决定。当然,SWT 是被Windows 窗体强迫进入这种情况的。
有关更多信息,“EDT”是一个不错的起点 http://en.wikipedia.org/wiki/ Event_dispatching_thread
对于.NET,SwingWorker 的等效项称为BackgroundWorker。
I think it's all about deadlock prevention.
Swing's components are not considered thread-safe, and they don't have to be because of this Event Dispatcher Thread. If the UI was multi-threaded, the whole app would have to rely on every component behaving itself in a thread-safe manner, and if any didn't, then deadlocks could arise in obscure situations.
So, it's just safer.
Not only that, but the same design has been chosen by Windows Forms (& .Net), GTK, Motif, and various others. I wonder if Java would have been forced into this decision by the underlying OS APIs which they interact with. Certainly SWT is forced into this situation by Windows Forms.
For more info, "EDT" is a good place to start http://en.wikipedia.org/wiki/Event_dispatching_thread
For .NET, the equivalent of SwingWorker is known as BackgroundWorker.
它们都不再是单线程的了。现代的现在都构建场景图并在不同的线程中渲染/组合它们。 Html 小部件不仅在多个线程中而且在多个进程中进行布局计算。
一般来说,随着 MVVM 模式的广泛使用,它对于复杂的模型来说没有任何意义。您可以从任何线程更新模型。恕我直言,这是其发明的主要原因,而不是数据绑定的论点。
如果您仅仅因为鼠标/按键/触摸事件全部到达一个线程而将其称为单线程,那么您可以进行哲学辩论。如今,操纵行为在许多地方都存在。 GPU 场景图是用数千个并行着色器渲染的,这如何应用于这个问题?
They are all not single threaded anymore. The modern ones all build a scene graph now and render/compose them in different threads. A Html widget does layout calculations not only in multiple threads but multiple processes.
In general with the widespread use of MVVM pattern it makes no sense for complex models. You can update the Models from any thread. IMHO this was the major reason for it's invention not the data binding argument.
You can debate philosophically if you call this still single threaded just because the mouse/key/touch events arrive all in one thread. Manipulations happen in many places nowadays. And the GPU scene graph is rendered with thousands of parallel shaders how does this apply to the question?
这是由 UI 应用程序的性质决定的。
您应该读取输入(鼠标或键盘),调度事件,让它们处理,然后再次绘制屏幕。
尝试在多线程进程上进行。
This is because of the nature of an UI application.
You should read the input (Mouse or Keyboard), dispatch the events, let them process and than draw the screen again.
Try do it on multi-thread process.