Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

When is a singleton not a singleton?

Avoid multiple singleton instances by keeping these tips in mind

  • Print
  • Feedback
The singleton is a useful design pattern for allowing only one instance of your class, but common mistakes can inadvertently allow more than one instance to be created. In this article, I'll show you how that can happen and how to avoid it.

The singleton's purpose is to control object creation, limiting the number to one but allowing the flexibility to create more objects if the situation changes. Since there is only one singleton instance, any instance fields of a singleton will occur only once per class, just like static fields.

Singletons often control access to resources such as database connections or sockets. For example, if you have a license for only one connection for your database or your JDBC driver has trouble with multithreading, the singleton makes sure that only one connection is made or that only one thread can access the connection at a time. If you add database connections or use a JDBC driver that allows multithreading, the singleton can be easily adjusted to allow more connections.

Moreover, singletons can be stateful; in this case, their role is to serve as a unique repository of state. If you are implementing a counter that needs to give out sequential and unique numbers (such as the machine that gives out numbers in the deli), the counter needs to be globally unique. The singleton can hold the number and synchronize access; if later you want to hold counters in a database for persistence, you can change the private implementation of the singleton without changing the interface.

On the other hand, singletons can also be stateless, providing utility functions that need no more information than their parameters. In that case, there is no need to instantiate multiple objects that have no reason for their existence, and so a singleton is appropriate.

The singleton should not be seen as way to implement global variables in Java; rather, along the lines of the factory design patterns, the singleton lets you encapsulate and control the creation process by making sure that certain prerequisites are fulfilled or by creating the object lazily on demand.

However, in certain situations, two or more singletons can mysteriously materialize, disrupting the very guarantees that the singleton is meant to provide. For example, if your singleton Frame is meant as a global user interface for your application and two are created, your application will have two Frames on the screen -- quite confusing for the user. Further, if two counters are created where one was intended, then clients requesting numbers will not get the desired sequence 1, 2, 3... but rather a multiple sequence such as 1, 1, 2, 2, 3, 3, 3.... Additionally, if several instances of a database-connection singleton are created, you might start receiving SQLExceptions complaining about "too many database connections."

In this article, I'll describe those phenomena and how to avoid them. After discussing how to implement the singleton, I'll go over the sometimes surprising causes for the phenomena one by one, showing you how they occur and how you can avoid making those mistakes. I hope that in the process you will learn about classloading, multithreading, distributed systems, Design Patterns, and other interesting topics, as I did.

  • Print
  • Feedback

Resources