Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Singletons with needles and thread

Two approaches to creating thread-safe singletons

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

January 25, 2002

In "Singletons Rule," "Effective Object-Oriented Design," and "n Class Instances," I addressed questions regarding the Singleton design pattern. As many readers have since pointed out, you must take special care to ensure that singletons are thread safe. With that in mind, in this Java Q&A I explore singletons and thread safety.

Let's begin by looking at a nonthread-safe singleton:

public class Singleton {
    private static Singleton instance;
    
    public static Singleton getInstance() {
        if( instance == null ) {
            instance = new Singleton();
        }
        return instance;
    }
    
    private Singleton() {}
    public static void main( String [] args ) {
        Singleton instance = Singleton.getInstance();
        // ... manipulate instance
    }
   
}


Unfortunately, in the example above, a thread may at any time pre-empt the call to getInstance(). For example, a thread may pre-empt a running thread at instance = new Singleton. If that were to happen, multiple Singleton instances might instantiate, thus defeating the purpose of a singleton.

To make a singleton thread safe, you have two choices. The first simply synchronizes the getInstance() method:

public class Singleton {
    private static Singleton instance;
    
    public synchronized static Singleton getInstance() {
        if( instance == null ) {
            instance = new Singleton();
        }
        return instance;
    }
    
    private Singleton() {}
    public static void main( String [] args ) {
        Singleton instance = Singleton.getInstance();
        // ...
    }
}


Synchronizing the method guarantees that a call to the method cannot be interrupted.

The second approach to thread safety declares a constant Singleton attribute on the Singleton class itself:

public class Singleton {
    public final static Singleton instance = new Singleton();
    
    private Singleton() {}
    public static void main( String [] args ) {
        Singleton instance = Singleton.instance;
        // ...
    }
    
}


instance will initialize when the class loades. Both solutions guarantee only one Singleton will exist.

In "n Class Instances," I presented an alternate approach to singletons that allows multiple instances of an object but caps the number of instances at some number. In that article, the following method retrieved the instance:

public static AlternateSingleton instance()
{
    return instances.next();
}


As you can see, instance() is not thread safe because it retrieves the instance from a nonthread-safe data structure. If a thread pre-empts instances.next() at the wrong time, the same instance may be returned multiple times in a row. Fortunately, fixing the problem is as easy as synchronizing the method:

public synchronized static AlternateSingleton instance()
{
    return instances.next();
}


Singleton discussion

Not everyone believes singletons represent the best design choice, while others believe that singletons have their place when used carefully.

When thinking about using a singleton, it is a good idea to check out the arguments for and against the pattern.

As one drawback, the Singleton as I implemented above makes inheritance impossible (the constructor is private). So you can lose some object-oriented programming (OOP) benefits when you decide to make a class a singleton. However, other approaches to implementing the Singleton pattern allow you to use inheritance or to treat the singleton polymorphically. For example, you can combine an interface, multiple implementations, and a factory to boost your singletons' flexibility. Let's examine each piece of this alternate approach.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources