当违反 Swing 的线程策略时会发生什么? [英] What happens when Swing's threading policy is violated?

查看:58
本文介绍了当违反 Swing 的线程策略时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去几年中,我主要在 Eclipse 中进行 UI 开发,这在线程访问方面非常保守:任何尝试从 UI 线程外部更改 UI 小部件上的属性(例如,颜色、文本)抛出异常.

In the past few years I've mostly done UI development in Eclipse, which is very conservative in terms of thread access: any attempt to change a property on a UI widget (e.g., color, text) from outside the UI thread throws an exception.

我现在正在查看 Swing 中的现有程序,该程序有一个带有大量自定义小部件的窗口.有一个单独的线程为这些小部件中的每一个运行一个变异函数,变异函数读取一些东西的值(例如,标签颜色和值)并写入一些东西(例如,改变背景颜色).请注意,没有涉及自定义绘画或类似的东西,只是对其包含的主要是 JLabel 的子小部件进行了一系列更改.

I am now looking at an existing program in Swing that has a window with a large number of custom widget. There is a separate threads that runs a mutation function for each of these widgets, and the mutation function reads the value of some things (e.g., label colors and values) and writes some (e.g., changes background colors). Note that there is no custom painting involved or anything like that, just a bunch of changes to the sub widgets it contains which are mostly JLabels.

目前,这是从单独的线程运行,而不是从 Swing 事件线程运行.该线程遍历所有 400 个小部件并在每个小部件上调用 mutator.更新似乎工作正常,但 GUI 对用户输入没有响应.

At present, this runs from the separate thread, not from the Swing event thread. This thread goes over all the 400 widgets and calls the mutator on each. The updates seem to work correctly, but the GUI is unresponsive to user input.

如果我从 Swing 线程外部运行大约 0.4 毫秒的整个过程,并将对增变器的每个调用都包装在 invokeLater 或 invokeAndWait 中,那么 UI 的响应速度会快得多.

If I take the whole thing, which runs for about 0.4 msec from outside the Swing thread and wrap every call to a mutator in an invokeLater or invokeAndWait, the UI is a lot more responsive.

我想了解的是:

1) 有时从 Swing 线程外部进行所有这些调用是否合法?

1) Is it sometimes legitimate to make all these calls from outside the Swing thread?

2) 对 Swing 线程有什么影响?为什么当我从外部调用它时 UI 响应速度变慢?

2) What is the impact on the Swing thread and why is the UI less responsive when I call it from outside?

推荐答案

从无"到间歇性问题,再到一切都坏了,让大家开始在 GUI 上工作!"

From "Nothing" to intermittent problems to "Everything Broke, pull everyone off to work on the GUI!"

主要的(最明显的)视觉效果是,如果您举起 GUI 线程(就像有人按下按钮然后您执行 sleep(5000) 或其他操作),您的 GUI 将不会重新绘制.它不能,因为你抓住了它允许通过你的唯一线程!这让人觉得Java真的很慢.这还不错,但很容易编程,以至于很多不费心研究这样的实践的人已经生产出运输产品.

The main (most obvious) visual effect is that if you hold up the GUI thread (like someone presses a button and you do a sleep(5000) or something), your GUI won't repaint. It can't because you are holding onto the only thread it's allowed to pass you! This makes people think Java is really slow. It's not bad, but it's easy enough to program that a lot of people who don't bother researching practices like this have produced shipping products.

下一个最大的问题是,当你在另一个线程中绘制屏幕时(比如传递给 main 的那个),它可能会出现奇怪的行为.Swing 对如何渲染帧已经太挑剔了——把线程作为一个变量!

The next biggest problem is that when you are drawing the screen in another thread (like the one passed to main), it can have strange behavior. Swing is already too picky about how you render your frames--take out threading as a variable!

最后,很少(或者经常,如果您在错误的线程上的紧密循环中调用摆动组件)您会发生线程冲突.如果发生这种情况,可能会抛出(或不会)异常,并且可能会出现错误,但可能并不明显.

Finally, rarely (or often if you are calling a swing component in a tight loop on the wrong thread) you can get thread collisions. If that happens an exception may be thrown (or not) and something will probably render wrong, but it may not be obvious.

这篇关于当违反 Swing 的线程策略时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆