Why does JDK 1.6 recommend creating Swing components on the EDT?

D

david.karr

When I first did Swing work several years ago, it was well known that
after Swing components were "realized", all access to them had to be
done on the Event Dispatch Thread. That means that ordinary assembly
of the required components, before they are shown, didn't have to
happen on the EDT.

It appears that the recommendations in JDK 1.6 have changed this. At
<http://java.sun.com/javase/6/docs/api/javax/swing/package-
summary.html>, in the "Swing's Threading Policy" section, it concludes
that ALL access to Swing components, even construction, has to be on
the EDT. This seems odd. Besides the statements at that javadoc
page, is there any justification for this change in strategy? Is
there really code now that executes in the constructor of a Swing
component that needs to execute on the EDT?
 
L

Lew

Peter said:
There may be some specific change that has led to the difference you're
seeing in the documentation (though frankly, I'm not sure this
recommendation really is new to 1.6), but I think it's more likely that
it's just that prior advice was flawed.  That it's always been the case
that you can't be assured that just because code is in the constructor
of a Swing component (or even simply code executed before some explicit
realization of the component, such as showing it), it's safe to execute
that code outside of the EDT, and that the current documentation is
simply fixing that oversight in past documentation.

That's exactly what Sun tells us - that they were mistaken when they
thought you could construct GUI components off the EDT. The advice to
put all GUI action on the EDT both prior to and after realization is
retroactive to all versions of Swing.

For the current wisdom, here are a couple of links:
<http://java.sun.com/docs/books/tutorial/uiswing/concurrency/
dispatch.html>
which contains an informative link to
<http://weblogs.java.net/blog/kgh/archive/2004/10/
multithreaded_t.html>

<http://java.sun.com/developer/JDCTechTips/2005/tt0419.html#1>
 
M

markspace

david.karr said:
It appears that the recommendations in JDK 1.6 have changed this. At
<http://java.sun.com/javase/6/docs/api/javax/swing/package-
summary.html>, in the "Swing's Threading Policy" section, it concludes
that ALL access to Swing components, even construction, has to be on
the EDT.


Yeah, Sun fuggered up their earlier recommendation and had to take it
back. Everything goes on the EDT now.

I think this may have had something to do with the new memory model in
1.5 when they really sussed all this stuff out and went "whoopsie" but
I'm just speculating there.

Besides actual thread safety and associated issues like visibility and
synchronization, there's I think a software issue. Swing components
often have "listeners" of some type, and these listeners are designed to
execute on the EDT.

Since these listeners are asynchronous and respond to events (like
property changes) it's possible to have these listeners fire as you
construct your GUI. The result is that some listeners are being
executed on the EDT as you are constructing in your main thread, and
some listeners might be running on some other thread as well (because
the listener is confused and fires on the wrong thread). The result is
a huge unpredictable mess.

The EDT synchronizes these issues because it doesn't allow any listeners
to run while it's busy doing something else. It's just one thread, it
can't, so the listeners are queued up and executed later, which is just
what you want.
 
R

Roedy Green

Yeah, Sun fuggered up their earlier recommendation and had to take it
back. Everything goes on the EDT now.

The problem is threading bugs are very hard to reproduce and track
down. My putting everything onto the EDT thread, they avoid a large
number of headaches.
 
A

Albert

Le 01/12/2009 09:54, Roedy Green a écrit :
The problem is threading bugs are very hard to reproduce and track
down. My putting everything onto the EDT thread, they avoid a large
number of headaches.

have you actually seen such a bug ? Something like corrupted data in a
swing model for example ? I've never triggered such a bug, even if i did
a lot of gui calls off the EDT.
 
L

Lew

Roedy Green a écrit :
have you actually seen such a bug ? Something like corrupted data in a
swing model for example ? I've never triggered such a bug, even if i [sic] did
a lot of gui calls off the EDT.

I've never actually seen Roedy but I know he exists.

Have you tried running improperly-threaded Swing programs on a multiprocessor
machine? Millions of times?

It took Sun, with its knowledge of millions of Java programs and some of the
very best minds in the computer world working on Java, years to figure out
that their earlier advice regarding Swing and the EDT was wrong. That's why
the OP thought maybe that the new advice was specific to the latest version of
Java when it actually applies to all versions of Swing. .Net has the same
advice.

This is why professional computer programmers read a lot. We know that our
own personal experience is limited so we seek out the wider experience of the
community at large and follow industry best practices. We would rather learn
from others' wisdom than have an expensive, embarrassing and entirely
avoidable problem at the customer site.

"But that never happened to me before!" will be small comfort then.
 
J

John B. Matthews

Albert said:
Le 01/12/2009 09:54, Roedy Green a écrit :
Yeah, Sun fuggered up their earlier recommendation and had to take
it back. Everything goes on the EDT now.

The problem is threading bugs are very hard to reproduce and track
down. y putting everything onto the EDT thread, they avoid a
large number of headaches.


have you actually seen such a bug ? Something like corrupted data in
a swing model for example ? I've never triggered such a bug, even if
i did a lot of gui calls off the EDT.


As an erstwhile apostate, I have to say yes, twice:

1) On a slow, dual-core machine, while creating a JTree with a complex
selection listener, but not on a comparable single-core machine.

2) On a fast machine with a poorly chosen value for the initial delay of
a timer, and then only once in a while.

As others have noted, the problems may me hardware dependent.
 
R

Roedy Green

have you actually seen such a bug ? Something like corrupted data in a
swing model for example ? I've never triggered such a bug, even if i did
a lot of gui calls off the EDT.

I vaguely recall reading about freezing bugs when you did not use the
EDT thread. They trickled out. I think Sun decided to put out this
warning, since presumably there were still more bugs not yet
discovered. This was a way of avoiding them.

You could have a look in the bug parade.

see http://mindprod.com/jgloss/bugs.html
 
A

alexandre_paterson

It appears that the recommendations in JDK 1.6 have changed this.

Yup...

I came to the realization that Swing was thread hostile. I now
do everything on the EDT and things are fine (well, as fine as
they can be with Sun / Swing's poor perfs... Latest joke upon
me was the hooplas I had to go true to get reasonable memory/CPU
usage using 'advanced' JTables. Thankfully I found Sun's
"Christmas tree" doc and while I was reading it I kept thinking
"wtf, this is a client app running mostly on Core 2 Duos, doing
billions of cycles per second, and painting a f***ing JTable is
*that* slow!?").

I hugely suggest using the ThreadCheckingRepaintManager:

https://swinghelper.dev.java.net/
 
N

Nigel Wade

Le 01/12/2009 09:54, Roedy Green a écrit :

have you actually seen such a bug ? Something like corrupted data in a
swing model for example ? I've never triggered such a bug, even if i did
a lot of gui calls off the EDT.

Yes, I have encountered such a bug. Just because you've never actually
experienced the problem does not mean that the problem does not exist, or
that it's safe to ignore it. You can never know when the bug will strike,
and this makes them almost impossible to track down. The symptoms vary,
as do their timing. It may run perfectly 99 times out of a 100. Or it may
work perfectly every time on one system, but fail on another.

In my case the GUI worked perfectly - most of the time. But every once in
a while some of the components were not drawn correctly when the GUI
first appeared. The components which were not fully drawn varied.

At that time the recommendation from Sun, as explained in the Java Swing
Tutorial, was that it was safe to create the GUI on the main thread until
such time as the first component was realized, when the EDT would be
started. From this point on (once the EDT was running) all subsequent use
of any Swing component should be done on the EDT. It was around the same
time as I was having my problem that Sun changed their advice on this
issue (and also updated the Tutorial - this was the 1.4/1.5 Tutorial,
prior to the re-write for 1.6). So I altered my code to follow their
advice and the problem went away, never to be seen again.

IIRC, Sun explained this by saying that certain components may, during
construction, perform operations which caused the EDT to be started even
though they had not yet been realized. Rather than working through the
source code for every single component to check what operations its
constructor performed and whether they started the EDT (and updating the
Javadocs accordingly), it was simpler just to advise that all components
should be constructed on the EDT.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top