Singleton Pattern: Am I implementing it Correctly? - Part I

Novice way to implement a Singleton:
I believe everyone starts (and even continues to do so) implementing Singleton pattern in following fashion:
package com.singleton;

public class SimpleSingleton {
 private static SimpleSingleton simpleSingleton;

 private SimpleSingleton() {
 };

 public static SimpleSingleton getInstance() {
  if (simpleSingleton == null)
   simpleSingleton = new SimpleSingleton();
  return simpleSingleton;
 }
}

Do you find any problem in it?
Well, I have!!! The contract of Singleton class can be broken. 
Let's discuss Singleton pattern in Simple Threaded environment and then in next post I will discuss this pattern in Multithreaded environment.

In a Single Threaded Environment:
Do you remember the double edge sword in Java, "REFLECTION"?
With the help of reflection, one can very easily breach the singleton contract for above class and create as many instance as he wants. Let's consider following three statements:
//Get Private Constructor
  Constructor pvtConstructor = Class.forName(
    "com.singleton.SimpleSingleton").getDeclaredConstructors()[0];
  
  //Set its access control
  pvtConstructor.setAccessible(true);
  
  //Invoke Private Constructor
  SimpleSingleton notSingleton = (SimpleSingleton) pvtConstructor
    .newInstance(null);

Here is a summary what is happening in above statements:
  • First statement retrieves the Constructor object for private constructor of SimpleSingleton class.
  • Since the constructor retrieved is a private one, we need to set its accessibility to true.
  • Last statement invokes the private constructor and create a new instance of SimpleSingleton class.
Clearly, we have breached the contract of Singleton class. So, how to overcome this problem?
Well, prior to Java 1.5, there was no way (at least in my knowledge, but Java Universe is so big that I can't say with 100% surity :) ) to save a singleton class from Reflection mechanism. In Java 1.5, a new kind of classes were introduced, "Enum".


Unlike Classes, an Enum has fix number of objects and since this restriction is implemented by JVM's native libraries, hence it is unbreakable. Let's see an example:
public enum SampleEnum {
 ONLY_INSTANCE();
}

Now let's try to create an object of SampleEnum using reflection:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class enumTest {
 public static void main(String[] args) throws ClassNotFoundException,
   IllegalArgumentException, SecurityException,
   InstantiationException, IllegalAccessException,
   InvocationTargetException {
  Constructor c1 = Class.forName("SampleEnum").getDeclaredConstructors()[0];
  c1.setAccessible(true);
  SampleEnum e1 = (SampleEnum) c1.newInstance(null);
 }
}
On running this example, it will throw an exception:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
 at java.lang.reflect.Constructor.newInstance(Constructor.java:511)
 at enumTest.main(enumTest.java:11)
Clearly, you can't create an object of Enum type.


Hence, we can conclude that best way to implement a Singleton pattern is by using Enum. It is simple, straightforward and unbreakable.


Further, in my next post, I will discuss about Singleton pattern in Multithreaded environment.

15 comments:

Arnab Biswas said...

Good Post. Using Enum for Singleton is the best choice I believe. But, Singleton itself is not a good OO design pattern. It is being called as an Anti-Pattern.


http://tiny.cc/qhhzu

Vineet Mangal said...

@Arnab: I agree upon the problems that you are pointing, but again isn't that because of the way Singleton is implemented. I think if we implement Singleton using Enums then most of arguments against Singleton stands invalid.
What do you say?

Erwin said...

The problem with the singleton is not the implementation, it's the idea behind it. A singleton is a global state, disguised in a class or object. It's the same as a global variable in procedural programming languages.

The same problems apply to it and as global variables a singleton is not necessary, but just laziness. Only because it's called a "pattern" it doesn't mean that it's a good idea to actually use it.

Dependency Injection is a much more preferred way to handle any use case of a Singleton. There are even a a lot of lightweight DI frameworks in Java, like Guice.

Artur Biesiadowski said...

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import sun.reflect.ConstructorAccessor;

public class BreakEnum {

public static void main(String[] args) throws Exception {
SampleEnum a = SampleEnum.ONLY_INSTANCE;
System.out.println(a.getClass() + " " + a + " = " + System.identityHashCode(a));

Constructor constructor = SampleEnum.class.getDeclaredConstructors()[0];
Method acquire = constructor.getClass().getDeclaredMethod("acquireConstructorAccessor");
acquire.setAccessible(true);
acquire.invoke(constructor);

Method get = constructor.getClass().getDeclaredMethod("getConstructorAccessor");
get.setAccessible(true);
ConstructorAccessor invoke = (ConstructorAccessor) get.invoke(constructor);
Object b = invoke.newInstance(new Object[] {"SECOND_ONLY_INSTANCE",1});
System.out.println(b.getClass() + " " + b + " = " + System.identityHashCode(b));

}

}


If you allow reflection, you can always break java assumptions. If your code is meant to protected from one kind of reflection only, it is meaningless.

Initializing singletons with enums is done because of the initialization for multithreaded cases (to avoid double-checked locking etc), NOT to avoid random reflection breakage.

Anonymous said...

Here is My singleton resume :

http://www.slideshare.net/ouertani/singleton-sum-2204910

Anonymous said...

The correct way to implement singleton is to not implement it at all. There is absolutely no reason to ever use this anti-pattern. Do yourself a favor and ask yourself whether you really want to introduce global state into your program. And if you do, is there a good reason to implement it using a singleton? Hint: there isn't.

Artur Biesiadowski said...

@Erwin

Dependency Injection might be helping with unit testing, but it doesn't change the fact that singleton is just a glorified global static value - DI or not.

In fact, I see a lot more of that kind of 'global value' stuff in Spring applications, because people think that having singletons in xml file is not bad anymore. Even if you have mutable, race-condition prone, broken code inside the Spring singleton bean instance.

Andy Y said...

It is possible to have more than 1 copy of an enum if your enum implemented Serializable. Have a google for enum and readResolve() which should show how someone could break the single enum instance assumption.

How much of a problem do you see this? If someone goes to these lengths to get around your singleton that to me would suggest your singleton is doing more harm than good.

Arnab Biswas said...

@Vinnet, as Erwin has mentioned the problem is not with the way Singletons are implemented, but with the way Singletons are being used. You can get instance of Singleton anywhere just by invoking the getInstance() method. No need to declare any dependency in the signature of the method from where you are invoking it. Thus unwanted/unknown dependencies get created. Moreover, such use of Singleton creates problem for writing the test code.

Singletons should be used properly and may be dependency injection is the best way to do so. This is the information I wanted to share in my blog. It does not have any thing to do with the way of implementation - Enum or Not!

Vineet Mangal said...

@All: Thanks for your valuable inputs. It is great to see you people to get involve in such kinda discussion. Now I have one more view of looking at Singleton Pattern.
@Erwin: Thanks for pointing me to Guice. It looks very good framework (I went through its presentation slides).

@Artur: Isn't sun.* packages are discouraged to be used? Plz see here, http://java.sun.com/products/jdk/faq/faq-sun-packages.html

I take comments/suggestion from all of you, and will further put my comments to resume this discussion

Artur Biesiadowski said...

@Vineet

Well, sun.* usage is discouraged, but do you think that using reflection to access private constructors and circumvent singleton pattern is encouraged practique?

Anonymous said...

Artur, you entirely missed the point of DI frameworks. The container-managed "singletons" in a framework like Spring are quite far from the true evilness of VM-wide singletons. If you want to create another one of those, you can. Of course you have to make sure that they are thread-safe, but this goes for any object you ever share across threads. Dependency injected singletons are not global - you cannot get access to one unless you specifically declare it as part of your interface (ok, Spring also allows member injection via reflection, but that is a discouraged practice). They are not really singletons, either - it's just a usage pattern that tells the DI framework: "every time you see me ask for Foo, give me the same instance of Foo". Unchecked proliferation of global state is what is the real problem with singletons (at least, the major problem, since there are others).

John Bannick said...

When did people forget KISS?
The Singleton is simple.
It doesn't rely on additional stuff like dependency injection or frameworks.
It can be communicated to Jr.programmers.
It can be understood at 0200 during Crunch.
And anyone who deliberately violates it via reflection is just dumb.
CummOn, folks: we're house builders, not artistes!

Vineet Mangal said...

I do feel that one shouldn't make a thumb rule that he should always avoid Singleton Pattern. I agree with most of the views presented here that Singleton Pattern also introduces other problems, but then there are instance where using Singleton is easier and better solution.

and @Artur: sun.* is discouraged because different java implementations can restrict its use (e.g. Sun's Java implementation restrict its use).
Further, the example you quote is similar like you want to break a Java Spec using native library, well actually you can break almost anything using native libraries.

Javin @ FIX Protocol Tutorial said...

Hi,
You can prevent creating multiple instance of Singleton using Reflection by throwing Exception from Constructor also.

Also you need to consider other aspect also while writing Singleton Class e..g
1) Lazy initialization
2) Early initialization
3) Serialization
4) Many ClassLoaders
5) Cloning


Thanks
Javin
Why String is immutable in Java