bitguru blog

a guru of bits, or just a bit player?

Archive for March 21st, 2007

Will the real Swing Single Threading Rule please stand up?

Posted by bitguru on March 21, 2007

disclaimer: This entry isn’t intended for a general audience. If you’re not a Swing programmer, you’ll probably want to skip it.

This is what a Swing “hello world” program used to look like.

import javax.swing.*;

public class HelloWorld2002 {

	public static void main(String[] argv) {
		JLabel bulletin = new JLabel("Hello, world!", JLabel.CENTER);

		JFrame frame = new JFrame("Bulletin");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(bulletin); // adds to CENTER
		frame.setSize(200, 150);
		frame.setVisible(true);
	}
}

This is pretty much the same as the code on page 85 of my book. In fact, just about all the examples in the book kick things off this way. They create JFrames and other JComponents in the main thread, either directly in main() or indirectly. Swing is not thread-safe (by design) so we have always had to be careful. For example, if we want to call bulletin.setForeground(Color.RED) after the frame is visible, we have to make sure it executes in the event-dispatching thread. If it executes in the main thread or some other thread it’s likely to work just fine, but there are no guarantees and it is possible that bad things (such as deadlock) may happen. Even if it seems to work on your development machine, it may fail intermittently, or it may even deterministically fail on some platform on which you haven’t tested or on some future release of the JDK.

Swing Single Threading Rule (through 2003)
Once a Swing component has been realized*, only the event-dispatching thread should affect or query the component.
*Realized means that the component has been painted onscreen, or is ready to be painted. The methods setVisible(true) and pack cause a window to be realized, which in turn causes the components it contains to be realized.

Several years ago I heard rumors that intermittent errors on the Solaris operating system could be worked-around by doing everything on the event-dispatching thread. By everything I mean not only the manipulation of realized components, but also of unrealized ones, and even the instantiation of the components themselves.

I never heard anything official in this regard, but it often pays to be cautious so I started doing this in most of my production code. I noticed that other Swing programmers started doing it in their code too.

Flash forward to last week. I was at a job interview. I had submitted a code sample that set up the GUI in the main thread, and now I was being asked about it. As a Swing expert, how could I have made such a common error?
Read the rest of this entry »

Posted in Java, Swing | 13 Comments »

 
Follow

Get every new post delivered to your Inbox.