What happens when a Swing thread policy is violated?

In the past few years, I have mainly done user interface development in Eclipse, which is very conservative in terms of access to the stream: any attempt to change a property in user interface widgets (e.g. color, text) throws an exception from outside the user interface.

Now I look at an existing program in Swing, which has a window with a lot of custom widgets. There is a separate thread that performs the mutation function for each of these widgets, and the mutation function reads the value of some things (for example, colors and label values) and writes some (for example, changes the background color). Please note that this does not have any individual coloring or something like that, just a bunch of changes to the widget subtypes, which contain mainly JLabels.

This is currently done from a separate thread, not from a Swing event stream. This thread spans all 400 widgets and calls a mutator on each of them. Updates seem to work correctly, but the GUI does not respond to user input.

If I take the whole thing that works for about 0.4 ms outside the Swing thread and completes every call to the mutator in invokeLater or invokeAndWait, the user interface is much more responsive.

I try to understand:

1) Is it sometimes legal to make all these calls because of the Swing thread?

2) What is the effect on the Swing thread and why is the user interface less responsive when I call it from the outside?

+6
java performance multithreading swing
source share
5 answers

From "Nothing" to intermittent issues with "Everything is broken, get everyone out to work with the GUI!"

The main (most obvious) visual effect is that if you delay the flow of the graphical interface (for example, someone presses a button and you sleep (5000) or something else), your graphical interface will not be redrawn. This is not possible because you are holding onto the only thread that you were allowed to go through! This makes people think that Java is really slow. It’s not bad, but just programming that many people who don’t bother researching such methods have released products for delivery.

The next big problem is that when you draw the screen in another thread (for example, the one that was transferred to the main one), it may have strange behavior. Swing is already too picky about how you render your frames - pull threads as a variable!

Finally, rarely (or often, if you call the swing component in a narrow loop on the wrong thread), you can get a thread collision. If this happens, an exception may be thrown (or not) and something will probably be wrong, but it may not be obvious.

+3
source share

1) Is it sometimes legal to make all these calls because of the Swing thread?

There are a few exceptions (setting the text value of a text field, for example, makes EDT automatically proxy for you), but there are no situations where it is better to do this. If you perform many updates, you can do them all with one click of EDT (one invokeLater () call) instead of separate calls, but even such sorting very rarely helps. Long and short: perform operations on Swing components from the EDT. This includes reading and writing.

2) What is the effect on the Swing thread and why is the user interface less responsive when I call it from the outside?

Well, EDT is responsible for updating the GUI. If you call from outside, this is no less “responsive” —that is, there are no actual low-level system calls that do not update the user interface. What probably happens in your application is that the original developers were lucky and the state in the swing component changed, without creating a really unpleasant race condition. Then, some other event causes a redraw on the EDT, which leads to the update of the component. This may seem like a “lack of responsiveness,” but what actually happens is the “lack of a screen update.”

EDT is just a regular thread, but it is slightly different in that it runs in a narrow loop that processes GUI-related signals (like drawing commands). The semantics of publishing these types of commands in EDT are really different from what we usually see as Java threads (this involves sending operations to the message pump).

Long and short - all of these Javadocs that say “only interact with Swing objects on EDT” are written for some reason. Do not get involved in this. If you want to do background processing, great, but you are responsible for proxying the interaction with J * components back to EDT (most often with invokeLater ()).

+3
source share
  • There are really no exceptions. Kevin is partially right - JTextComponent.setText () is advertised as thread safe. However, looking at code 1.6, it provides synchronization with the document object and does not use EDT. This is normal if another swing component (or something that controls swing components) does not listen to the document object. Save yourself from worrying about it, and always use EDT, as Kevin says, there really aren't situations that I know of to do otherwise.

  • It's hard to say without breaking into code; undefined behavior. If your background tasks were lengthy (> a few seconds), you will see the opposite effect - using EDT will make the user interface immune during the execution of your tasks.

Fortunately, it sounds like it works correctly for you anyway. :)

Sun used to say that it was normal to use other threads with components that were not implemented but later edited:

Stack related question

Check out the Sun UI tutorial on swing and concurrency (I would post a link, but this is my first answer on stackoverflow0.

+2
source share

The main problem is that non-thread objects are multithreaded. Even something as simple as reading a HashMap can be caught in an endless loop. Since AWT uses locks (poorly), you may also be at a dead end. However, you are likely to leave with it, although you may find that an updated version of Java suddenly causes problems on some client machines.

(BTW: It AWT Event Dispatch Thread, not Swing's.)

+1
source share

For (1), as a rule, everything that updates the pixels on the screen should be called from the Event Dispatching Thread (EDT) . If some JVMs can handle updates outside the EDT acceptable, you should never rely on this work, some machines and other looks will not work acceptable. The behavior is undefined - and this may explain the lack of reaction that you saw.

+1
source share

All Articles