Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / December 2003

Tip: Looking for answers? Try searching our database.

Pedantic Swing threading question

Thread view: 
Laird Nelson - 29 Dec 2003 14:05 GMT
Hello; hope everyone had a good holiday season.

I am familiar with Swing threading issues except for this one point.

Suppose you have a class, A, that registers itself (or another tiny
class) as a PropertyChangeListener on another class, B.  Suppose that
this PropertyChangeListener's job is to react to the property change
event by updating the GUI.

Strictly speaking, shouldn't the body of the propertyChange() method
always check to see if it's running on the event dispatch thread (EDT)
before actually attempting to update the GUI?

Now, I know that in most Swing applications, this is rarely a
concern--some text property changes somewhere and the listener simply
calls something like, say, JLabel.setText(), and that's a quick enough
call that it would probably be overkill to call
SwingUtilities.invokeLater().  But I'm interested in the...theory, I
guess, more than the actual practice.  For this thought experiment,
assume that the propertyChange() event may be invoked on a different thread.

Hope this question makes sense.

Cheers,
Laird
Bill Tschumy - 29 Dec 2003 14:16 GMT
> Hello; hope everyone had a good holiday season.
>
[quoted text clipped - 17 lines]
> assume that the propertyChange() event may be invoked on a different
> thread.

Using invokeLater() will still result in the code being executed on the
event thread since that is how it works.  I guess what you need to worry
about is someone starting a different thread and doing the setText from
that. Of course, doing so would be a bug and then the question comes
down to how much code should you write to shield yourself from bugs.

Although I seldom do it, I might agree with making a call to a method
that checks if it is the event thread and log an error if not.  I
probably would not go so far as to create a Runnable and use
invokeLater() to ensure my properyChange code executes on the event thread.

Signature

Bill Tschumy
Otherwise
www.otherwise.com

Todd Corley - 29 Dec 2003 20:35 GMT
> I guess what you need to worry
> about is someone starting a different thread and doing the setText from
> that. Of course, doing so would be a bug

Not really, setText is one of the very few thread safe methods in swing.
The actual update of the text component done in the event thread.
Jim Sculley - 29 Dec 2003 20:56 GMT
>>I guess what you need to worry
>>about is someone starting a different thread and doing the setText from
>>that. Of course, doing so would be a bug
>
> Not really, setText is one of the very few thread safe methods in swing.

Except it isn't.  See:

http://www.chka.de/swing/text/threads.html

Jim S.
Filip Larsen - 30 Dec 2003 13:32 GMT
Todd Corley wrote:

> > Not really, setText is one of the very few thread safe methods in swing.

and Jim Sculley answered

> Except it isn't.  See:
> http://www.chka.de/swing/text/threads.html

This is certainly nice to know. While this clearly is a bug and Sun mean
Documents to be thread safe, I cannot help thinking that the concept of
thread safe in Swing perhaps is a bit muddled. In the "Threads and
Swing" [1] article the authors mention the "single-thread rule":

"Once a Swing component has been realized, all code that might affect or
depend on the state of that component should be executed in the
event-dispatching thread."

Then they go on to to say that there are exceptions to this rule, and
such exceptions are marked with "this method is thread safe". If we call
methods that are allowed to break the single-thread rule for dispatcher
safe, then with the usual meaning of "thread safe" we have that thread
safe implies dispatcher safe, but dispatcher safe do not imply thread
safe.

Unfortunately, the article do not appear to make a destinction between
the two concepts and also I suspect that many people mean dispatcher
safe when they say thread safe in the context of Swing methods. This
begs the question if Sun really mean thread safe every time they mark a
Swing method as such?

[1] http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

Regards,
Signature

Filip Larsen

Harald Hein - 29 Dec 2003 16:56 GMT
> Strictly speaking, shouldn't the body of the propertyChange()
> method always check to see if it's running on the event dispatch
[quoted text clipped - 8 lines]
> experiment, assume that the propertyChange() event may be invoked
> on a different thread.

This is a problem for all possible events that can be fired by a
component. Property changes might just be the most obvious ones. Event
listeners are nothing but callback methods, and there is really nothing
in Swing or Java that will ensure that an event listener will indeed
always be called from the EDT only.

If you tamper with a component (maybe subclass), it should be possible
to fire each or at least most events of the particular component from
outside the EDT. And since the event listeners are just callback
methods, one could even call the methods completely separately from
Swing, and from another thread if one has the necessary object
reference.

So in theory on should check in each and every event listener method if  
it is invoked from the EDT. In practice, I would not do this at all! If
you have written clean code, this is something that shouldn't happen at
all. But, because things that shouldn't happen sometimes happen, you
might consider to add some assert() calls to your event listeners. I
would also not do this (it never happened to me, and I am lazy :-)),
but if you feel unsafe and need some hints for debugging, why not?

Back to property changes. I see a particular problem with those, which
some might want to investigate further. There are some very few Swing
methods which are marked as thread save, and can be called from outside
the EDT. If one such method triggers a property change event, I would
guess the event listeners are not called from the EDT, too. But that's
a guess, and someone would have to spent some time to come up with a
real example.
Filip Larsen - 29 Dec 2003 17:16 GMT
> Suppose you have a class, A, that registers itself (or another tiny
> class) as a PropertyChangeListener on another class, B.  Suppose that
[quoted text clipped - 4 lines]
> always check to see if it's running on the event dispatch thread (EDT)
> before actually attempting to update the GUI?

Yes, in the general case it should.

I use an adapter class to propagate PropertyChangeEvents when they may
be generated in another thread than the GUI dispatcher thread. The
following snippet contains the essential parts of it:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.SwingUtilities;

public class SwingPropertyChangeListener
implements PropertyChangeListener {

private final PropertyChangeListener listener;

public SwingPropertyChangeListener(PropertyChangeListener listener) {
 this.listener = listener;
}

public void propertyChange(final PropertyChangeEvent evt) {
 if (SwingUtilities.isEventDispatchThread()) {
  listener.propertyChange(evt);
 } else {
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    listener.propertyChange(evt);
   }
  });
 }
}
}

Note that if this pattern is used for other types of events that have
mutable properties and which are reused by the emitter, additional code
is needed to avoid a race condition. The above code do not have that
problem since PropertyChangeEvent (in practice) is immutable.

Regards,
Signature

Filip Larsen

Laird Nelson - 29 Dec 2003 17:29 GMT
> I use an adapter class to propagate PropertyChangeEvents when they may
> be generated in another thread than the GUI dispatcher thread. The
> following snippet contains the essential parts of it:

[snip]

Thanks; that's exactly what I thought.  I take the other poster's point
that in most cases you don't have to do this, and in many cases indeed
you /shouldn't/, but I just wanted to see if this was the approach to
take in the strictest of all possible cases.  I am not planning on using
this code in my existing application, as it's way too simple and doesn't
involve any other threads, but I wanted to make sure I had a handle on
the Swing threading model and its gotchas.

Thanks again,
Laird


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.