Re: invokeLater and weird race conditions in my swing app
Lew wrote:
Nigel Wade wrote:
The EDT is started by the JVM when you realize the first GUI component. From
this time forward all modifications to the GUI should be handled by the EDT.
Actually, even before this point one should only do GUI on the EDT. That
"after it's realized" rule turned out to be unsafe.
See
<http://www.javaworld.com/javaworld/jw-08-2007/jw-08-swingthreading.html>
page 3.
Yes, I was still working off the old script...
There are subtle side-effects which can bite you if you don't perform the entire
GUI initialization in the EDT. It's rare, but very, very difficult to diagnose
if you get bitten by it. I should have remembered, I've been there...
Using SwingUtilities.invokeLater() is one way of doing this. [There are a few
exceptions in that you are allowed to invoke some methods of some components
from other threads, but it's simplest if you treat all methods of all Swing
components as non thread-safe.] I think the reason Swing does this is that if
the components were made thread safe by internal locking the GUI interface
might well respond too slowly. So they are not locked, and the single-thread
rule must be obeyed.
That's not the reason. Swing is single-threaded because the designers found
that it's infeasible to write a multi-threaded GUI API.
IIRC X/Motif is (or at least it was) inherently single-threaded. I have some
That's true. It's cited (amongst others) in the articles that explain why
Swing is single-threaded.
If you are using Java 1.6 then look at the SwingWorker class. This ought to
be
able to do what you require. Also, read the tutorial on "Creating a GUI with
JFC/Swing" at http://java.sun.com/docs/books/tutorial/uiswing/TOC.html, in
particular the section on How to Use Tables. This could provide you with some
valuable assistance.
From Java 1.2 through 5, use java.awt.EventQueue.invokeLater() and its kin.
There used to be a SwingWorker which Sun provided, but was not part of the
standard API. I think this was the basis for the SwingWorker which is in 1.6.
All the old references to SwingWorker have been removed from the Tutorials, so
I couldn't reference it for previous releases. I think it was rather bad of Sun
to completely remove the old Tutorials, and the resources which went with them,
for previous releases when they updated the Tutorials for 1.6.
<http://java.sun.com/javase/6/docs/api/java/awt/EventQueue.html#invokeLater(java.lang.Runnable)>
It's tricky to get this right even so. /Java Concurrency in Practice/ by
Goetz, et al., has good material on it. The Swing chapter (Chapter 9) is
available on line as a sample chapter, I believe.
*All* concurrency is difficult to get your head around. When GUIs, and events,
and humans are involved it gets so much more complicated.
SwingWorker is a beautiful solution.
Indeed.
It's just a pity that Sun consigned the old version to the bit-bucket.
--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : nmw@ion.le.ac.uk
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555