Why Swing components should be accessed on the Event Dispatch Thread only? [closed]
Asked Answered
G

2

5

The above statement is mentioned in the SwingWorker javadoc.

In an application I have seen a lengthy background task runs in a distinct thread and updates the UI as well without a problem (a reference to a Swing component was accessible).

Could it be that something bad can happen?

Geomorphic answered 26/2, 2015 at 7:39 Comment(4)
"Could it be that something bad can happen?" - Yes. Simply put, Swing is not thread safe, it does not guard against multiple threads from accessing different properties which could mean you get into an inconsistent state. Remember, you don't control the paint process, so something might be getting painting while your changing it...these problems are difficult to replicate and track down and the worse thing is, they seem to only happen on your users machines....Gabey
Don't kid yourself, this is really, really dangerous and a really, really bad ideaGabey
1. why, 2. my curiosity really reason to post a question about, 3. note there is huge difference in Thread safety between Java6 and Java7/8, 4. voting to close as too broad (without an SSCCE/MCVE, short, runnable, compilable, with hardcoded value for Swing GUI in local variable)Mastoid
@Mastoid fortunately the question drew enough attention before you considered it too broad and two people contributed very acceptable answers to the question. Obviously, part of the community considered it constructive as well and other people were helped by the answer and comments. A very high percentage of SO questions do not meet your (4) criteria, though people who asked the question found answers that helped them, and many times helped others as well.Geomorphic
T
6

It's because the Java memory model does not guarantee that memory writes by one thread will be visible to other threads unless you use some form of synchronization. For performance and simplicity, Swing is not synchronized. Therefore, writes from other threads may never be visible to the EDT.

The application you've seen may work most of the time, and it may even work all of the time in some environments. But when it doesn't work, it'll fail in really strange ways that are difficult to reproduce.

Tiphany answered 26/2, 2015 at 7:49 Comment(2)
Here's an argument about why Swing has to be singlethreaded. "For simplicity" makes it sound like design lazyness or a flaw.Amalgamate
@Amalgamate Great read, and I think that applies to more than just UI toolkits. Many multi-threaded programs could be greatly simplified by a single-threaded event queue approach. And when it comes to software, I'd say "simplicity" has a strongly positive connotation. :)Tiphany
A
5

All Swing components are implemented to be accessed from a single thread (the event dispatching thread). So there are no protections against concurrent access and concurrent changes of variables and field.

If you are lucky everything works well. But you cannot rely on it and the same code can have massive problems on the next run.

A simple example:

The paint procedure of a JLabel contains the following (simplified) code (taken from BasicLabelUI class):

   # assume your label is enabled
   Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();

   # what happens if another thread calls label.setEnabled(false) at this point?

   if (icon != null) {
      icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
   }

   if (label.isEnabled()) {
         paintEnabledText(label, g, clippedText, textX, textY);
   }
   else {
         paintDisabledText(label, g, clippedText, textX, textY);
   }

For example if you call setEnabled() from other threads than the EDT it would be possible that you get a label with the enabled icon but the disabled painted text.

Art answered 26/2, 2015 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.