Threads Versus The Singleton Pattern

The Simple Singleton Factory

Consider that you decide you do not want to instantiate multiple Helper objects—you only want one Helper object to exist. One reason for this decision is that you might have several methods in several classes that all need access to the same "state" information. That is, things are spread out farther than the simple (and admittedly contrived) do-while loop shown above. In that case, a common solution is the arrange for a factory class to provide, via a static getter method, just one instance of the Helper. Consider this simple HelperFactory class, whose job is to ensure that, when asked, it only hands out the same singular instance of a Helper class:

The usage code above changes from Helper helper = new Helper(); to Helper helper = HelperFactory.getHelper();. Now, for that demonstrational code block, little is gained. But in a real application where, as I mentioned, your working code is spread far and wide, yet tied to the same progression of state, each interested piece of code can directly access this common, application-static Helper object via this factory getter method. (The alternative is fairly cumbersome: pass the same Helper object around in all your method calls. Enjoy the additional maintenance headaches for doing so while you're at it!) Because my assumption for this article is that you are familiar with this pattern, I won't dwell on it further.

Threaded Headaches

Now, amend your usage code somewhat to reside in the "run()" method of a Thread-derived class. Note that you also will change the println statements slightly to display the name of the thread so you can more clearly identify which thread is emitting which message. More importantly, you access a singleton Helper object via the simple factory shown above:

All output sections are different, and given the random variation of the sleep timer, this is somewhat expected. More importantly, all three are wrong—in none of them does any one thread print messages for all three helper states. (Although for different purposes you might desire the effect shown, it is wrong for the purposes of this article.) This is, at last, a visual illustration of how the two threads compete with each other for the state of the same singleton Helper object. The failure point, and the solution, lie in the factory class itself.