RSS Feed Subscribe to RSS Feed

 

Singleton implementations

A singleton is a class that is instantiated exactly once (or at least, once per classloader). It is considered to be an anti-pattern by many (including me!) because it makes unit testing difficult. You can’t substitute a mock implementation for a singleton (unless it happens to implement an interface, which I haven’t seen too often). And singletons also make your APIs into liars.

However, if you do want/have to use singletons, this article discusses the best approach.

Simple approach

The simplest way to implement a singleton is with a private constructor and a public static member. That member can be a method, e.g.

public class Singleton {
	private static final Singleton instance = new Singleton();
	private Singleton() {}
	
	public static Singleton getInstance() {
		return instance;
	} 
}

Or the public member can be a field, e.g.

public class Singleton {
	public static final Singleton INSTANCE = new Singleton();
	private Singleton() {}
}

Singleton with lazy instantiation

One problem with the above approaches is that they do not use lazy instantiation. Lazy instantiation is perhaps an overused technique (see Item 71 of Effective Java – use lazy instantiation judiciously), but it can be useful in situations where a field is used in only a fraction of classes and it is expensive to create.

If you do decide to use lazy instantiation, something like this will work, but is NOT threadsafe:

public class Singleton {
	private static Singleton instance = null;
	private Singleton() {}
	
	public static synchronized Singleton getInstance() {
		if (instance == null) { 
			instance = new Singleton();
		}
		return instance;
	}
}

In order to make this code threadsafe, there are a two main options:
1) Make the getInstance method synchronized (although obviously this will have a performance hit)
2) Use the lazy initialization on demand holder idiom, e.g.

public class Singleton {
  private Singleton() {}
  private static class SingletonHolder { 
    private static final Singleton INSTANCE = new Singleton();
  }
  public static Singleton getInstance() {
    return SingletonHolder.INSTANCE;
  }
}

This approach works on all known versions of Java and takes advantage of the fact that a class is not initialized until it is used.

Singleton limitations

All the above solutions have some notable issues in that using them will not necessarily result in a class that is only instantiated once! If your singleton class implements serializable, it is possible for an instance of the class to be serialized once, then deserialized many times, resulting in many instance being created. There are also sophisticated attacks on the uniqueness of a singleton that can be done using reflection.

Recommended approach – enum

The following solution is completely thread safe, prevents against both the serialization and reflection ‘attacks’ and is by far the simplest approach.

public enum Singleton {
	INSTANCE;
}

This approach utilizes the fact that enum constants are constructed the first time the class in use and is the approach recommended by Josh Block in his Effective Java book (2nd edition), where he says “a single-element enum type is the best way to implement a singleton”.

It is not without its disadvantages either however, including

  • Only available in Java 5 or above
  • It is unconventional. Most developers, especially junior ones, are likely to be unfamiliar with this approach.
  • As an enum, your singleton cannot extend any other class (you can only implement interfaces)
  • Your singleton now has access to other methods which might not make a lot of sense, such as ordinal() and values()

None the less, these are relatively minor points and, if you are using Java5 or above, this is likely to be your best bet for implementing a Singleton.

Reading/references

Effective Java 2nd edition
Item 71: Use lazy initialization judiciously
Item 3: Enforce the singleton property with a private constructor or an enum type

Tags:

3 Responses to “Singleton implementations”

  1. Random Fletch |

    Woah, I kept trying to find the date to work out if this was an April fools. Dude, Singletons are bad enough. Wrapping them up in an Enum makes them even scarier.

    Dependency Injection is your friend.

  2. admin |

    Hey,
    I agree that singletons can be ‘bad’ – I did say in my intro that I consider the singleton to be an anti-pattern that makes unit testing very difficult. And, yes Dependency Injection can be a great approach (I have given talks on Spring).

    The article is about what Singleton implementations are best if you want/have to use them, not if Singletons are a good idea. And, all things considered, the enum solution ticks all the boxes: thread safe, lazy instantiation and protection against serialization issues without the need for complicated work arounds. They are also the approach advocated by Josh Bloch, the author of the Collections API. I highly recommend you read his book, Effective Java.

    So, I guess the question to you is: If you are going to use a Singleton, why do you think the enum approach is bad?

    Shaun

  3. manoj |

    Visit http://efectivejava.blogspot.in/ and know how lazy initialization affect the performance.
    How lazy can we afford to be???

Leave a Reply