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?

yannisf
  • 6,016
  • 9
  • 39
  • 61
  • 2
    *"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.... – MadProgrammer Feb 26 '15 at 08:35
  • Don't kid yourself, this is really, really dangerous and a really, really bad idea – MadProgrammer Feb 26 '15 at 08:38
  • 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) – mKorbel Feb 26 '15 at 10:23
  • @mKorbel 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. – yannisf Feb 26 '15 at 19:27

2 Answers2

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.

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
  • [Here's](https://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html) an argument about why Swing *has* to be singlethreaded. "For simplicity" makes it sound like design lazyness or a flaw. – DSquare Feb 26 '15 at 08:43
  • @DSquare 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. :) – Kevin Krumwiede Feb 26 '15 at 08:58
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.

Uli
  • 1,390
  • 1
  • 14
  • 28