|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 5
The thread-safety issue is an important one. Swing's threading support is described in depth in a Tech note on the Sun Web site, but to summarize: Swing, like AWT before it, uses a single thread to field all user interface (UI) events
that come in from the operating system. This thread dequeues OS events from some sort of event queue, figures out what the
OS is trying to tell it, and then notifies any listeners interested in the event. For example, the event thread could dequeue
a WM_MOUSEMOVE message from the Windows message queue, and then send out mouseMoved() messages to all the interested MouseMotionListener objects.
These event handler methods (such as mouseMoved()) actually run on the thread that's dequeueing the OS-level events. This single-threaded approach is a big issue, because the UI is effectively locked while the event handler messages are executing.
That is, no OS-level messages (such as button presses) are serviced while listener notifications are in progress. To keep
your UI responsive to user input, these event handler functions should be very short and very fast. They must spawn off threads
to do time-consuming operations.
To make matters more interesting, none of Swing class's methods are thread safe -- they are simply not designed to handle
the case of two threads accessing them simultaneously. The performance hit required to make Swing thread-safe (not to mention
the extra complexity) is just unacceptable. The lack of thread safety means that once you start up the Swing event handler
thread (by calling setVisible(), pack(), or any other method that makes a window visible), you cannot safely call a Swing method from anywhere but Swing's own event
handler thread. (Note that you can safely manipulate Swing objects before the event handling thread starts -- before you call setVisible() or pack(), for example.)
The lack of thread safety is often not an issue because Swing methods are, more often than not, called from Swing's own event
handler thread -- remember, all the listener methods run on that thread. For example, a listener's event handler like mouseMoved() might pass a repaint() message to some Component. This operation is safe because mouseMoved() is running on Swing's own thread.
The invokeLater() and invokeAndWait() methods
There are often cases where some thread of your own devising needs to communicate with Swing, however. For example, the main
thread of an application could fire up a window, do some stuff, then want to modify the window. Since you obviously need to
pass messages to Swing at times other than initialization time, a mechanism has been provided to ask the Swing event-handling
thread to execute a block of code for you. You need to encapsulate your code into a Runnable object, and then pass that object to Swing by calling SwingUtilities.invokeLater() or SwingUtilities.invokeAndWait(). For example, a thread could force a window to redraw itself like this:
Component some_window = ... ;
Swingutilities.invokeLater( new Runnable()
{ public void run()
{ some_window.repaint();
}
}
);
The asynchronous invokeLater() message just puts the Runnable object onto the event queue and then returns. The object's run() method is executed when Swing gets around to it. The invokeAndWait() method blocks until the run() function has been executed. Since the associated run() methods run on the Swing event handler thread, synchronously with other Swing methods, the thread safety of the individual
Swing methods is irrelevant.
com.holub.asynch package) is available in the "Goodies" section on my Web site, http://www.holub.com. The version on the Web site should be considered the definitive version -- at least it corrects any bugs I know about.
Timer class in the JDK docs and at http://java.sun.com/products/jdk/1.2/docs/api/javax/swing/Timer.html