Breaking singleton pattern

All over the web you can find several articles describing and motivating the “evilness” beyond singletons.

A brief recap.

Singleton is one of the most used and abused design pattern available from GoF. While it is everywhere, it is now considered an anti-pattern, for a bunch of good reasons:

Difficult to test: It is quite difficult to isolate code inside a singleton without starting a real istance of it. Just imagine if your singleton starts a server… the test becomes very painful, hard to start, long to run and impossible to mock.

Thread safety: it is very easy to forget even the most basic thread safety rule when implementing the singleton pattern.

Global State: singletons instroduce global state into a program and this generates a tie between classes. It is widely accepted that code loosely coupled is easier to maintain, extend, use, fix.

The focus of this article is on thread safety and I want to demonstrate how to break a singleton bad coded..and how to avoid it.

Let’s start to code:

Here a bad implemented singleton:


package it.nicogiangregorio;

public class WorstSingleton {
   private static WorstSingleton oldSingleton;

   public static WorstSingleton getInstance() {

   if (oldSingleton == null) {
     oldSingleton = new WorstSingleton();
   }
   return oldSingleton;
  }

 private WorstSingleton() {

   try {
      Thread.sleep(5000);
   } catch (InterruptedException e) {
   // TODO Auto-generated catch block
      e.printStackTrace();
   }
 }
}

Inside the constructor the code: Thread.sleep(5000); helps simulate a computational expensive operation, such as a DB connection creation or other resource acquisition.

Then we need a starter class that is used to instantiate the singleton and prints the hashcode of the object.


package it.nicogiangregorio;

public class SingletonStarter implements Runnable {

@Override
 public void run() {
 System.out.println(WorstSingleton.getInstance().hashCode());
}
}

And now we write a Client class that will start N-threads of SingletonStarter that will run concurrently.


package it.nicogiangregorio;

public class Client {
 public static void main(String[] args) {
 for (int ii = 0; ii < 10; ii++) {
 new Thread(new SingletonStarter()).start();
 }
 }
}

In the main it starts 10 thread each one trying to instantiate a new instance of our ugly singleton. Run and see the output!!

14978587
14978587
14978587
14978587
25669322
25669322
3195425
25669322
14978587
18426253

Argh!! How many instances!!!! Awful! We want one and only one object and the result is a resource leak.

Now let’s see a solution hugely adopted in the java version pre Java 1.5:


package it.nicogiangregorio;

public class FixedSingleton {
 private final static FixedSingleton fixedSingleton = new FixedSingleton();

public static FixedSingleton getInstance() {

return fixedSingleton;
 }

private FixedSingleton() {

try {
 Thread.sleep(5000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
}

The subtle technique to obtain thread safety is to create a final static field. The JVM specification guarantees initialiser will be executed only once, at class load time, via:

new FixedSingleton();

Re-write the starter class:


package it.nicogiangregorio;

public class SingletonStarter implements Runnable {

@Override
 public void run() {

 System.out.println(FixedSingleton.getInstance().hashCode());

 }
}

The Client class remains the same.

Output now is:

25669322
25669322
25669322
25669322
25669322
25669322
25669322
25669322
25669322
25669322

Wonderful!!! It works!!!

Wait..wait.. This solution works, yes, but still there are some issues to take into consideration.

1. If there are more then one Classloader, you are in trouble. It might happen that a singleton is started from two different classloader and you have two isntances. But it is very rare. The real problem is that your code is still vulnerable to reflection attacks!

Reflection can exploit these kind of issues to generate more than one instance of our singleton.

2. Serialization, you have to implement serialization policy if it is needed by your singleton.

Starting from Java 1.5 you have one more solution, more elegant, fully working, without drawbacks (as far as I know).

Singleton code:


package it.nicogiangregorio;

public enum OptimalSingleton {
 INSTANCE;

OptimalSingleton() {
 try {
 Thread.sleep(5000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
}

Thread starter:


package it.nicogiangregorio;

public class SingletonStarter implements Runnable {

@Override
 public void run() {

System.out.println(OptimalSingleton.INSTANCE.getClass().hashCode());

}
}

And the client remains the same.

The output will be:

19770577
19770577
19770577
19770577
19770577
19770577
19770577
19770577
19770577
19770577

Even this time we obtain a correct result, but the difference with the previous one is that now we have serialization and the enum is not vulnerable to Reflection attacks.

Special thanks to Francesco Fontana (maybe the link is to an empty page..there is one developer lazier than me!).

Feel free to leave a comment:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s