Swing Hangs on Thread, Old Timers to Blame, Factory Fixes
Potential RPG August 24th. 2007, 12:38pmElderly swing-set factory employees using thread instead of chains forces product recall?
No. Why would you think that?
This article describes how the javax.swing.Timer utility can cause your Swing application to hang at shutdown, and how to fix it.
The Timer utility is useful for repeating tasks on the Swing/AWT thread. They’re handy enough to create in many places throughout GUI code. However, each one that remains active keeps the AWT thread alive, which prevents clean application shutdown (without resorting to System.exit()). Lacing the code with Timer instances makes it difficult to track them all down and stop them when the application is supposed to exit.
To correct the situation for the MMORPG client, I created a simple factory class with a create(..) method for producing Timer instances. The factory maintains a reference to every Timer created. At application shutdown, the factory’s stop() method is called, which tells each Timer to stop(). After replacing all Timer constructor calls with the factory’s create(..) method, the MMORPG client exits cleanly.
There are a few caveats. For one, you must be certain it is safe to stop Timers in this way (a Timer may be carrying out some critical pre-shutdown operation). In general, I only use Timers for GUI-related activities, and not to drive application logic. Another weakness is that the factory cannot guarantee the Timers will not be restarted, or that more timers will not be created, after stopping the factory. This could be guarded with a more sophisticated design, such as a TimerProxy class to prevent post-shutdown starting, refusing to create new timers after shutdown, or an isStopped() method for GUI code to query.
For the MMORPG client, this simple factory pattern is sufficient to untie Timers from the AWT thread, allowing clean shutdown without resorting to System.exit().






September 4th, 2007 at 2:05 pm
You might also consider (if you haven’t) that the list kept by the factory be a list of WeakReferences to Timers. If a Timer stops itself and is no longer used, you don’t want the factory keeping a reference to it.
September 4th, 2007 at 2:20 pm
Good thought. Congratulations (and thank you) for posting the first non-spam comment.