Singleton Pattern Java With Double Locking and Without Cloning | Java @ Desk
Home » » Singleton Pattern Java With Double Locking and Without Cloning

Singleton Pattern Java With Double Locking and Without Cloning

Singleton Pattern Java With Double Locking and Without Cloning
In our last post we have seen how to apply double locking for singleton object creation so that multiple threads do not enter the method and instantiate the object. Refer Double Checked Locking in Singleton.

We also must prevent object creation using the cloning of objects. So we must ensure that the singleton class must override the Object clone() method and throw the Exception in that.

Complete example of Singleton with Double Locking and without cloning as shown below. Thread.sleep is just for the demo purpose. Just to understand the flow as our memory does not work as fast as JVM :)

package com.doubleLock;

public class SingletonDoubleLocking {

 private static SingletonDoubleLocking singletonDoubleLocking = null;

 private SingletonDoubleLocking() {

 }

 /** 
  * synchronized so that multiple thread do not enter the method
  * @return SingletonDoubleLocking
  */
 public static synchronized SingletonDoubleLocking getSingletonDoubleLocking() {
  if (singletonDoubleLocking == null) {
   System.out.println("Object is null");
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   singletonDoubleLocking = new SingletonDoubleLocking();
  }
  System.out.println("SingletonDoubleLocking - "
    + singletonDoubleLocking);
  return singletonDoubleLocking;
 }
 /**
  * Override clone method so that clone is avoided
  */
 @Override
 public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("Thrown this exception in order to avoid the creation of copy of this object");
    }
}


Client file to test the double locking and cloning


package com.doubleLock;

public class ClientSingletonDoubleLocking implements Runnable {

 public static void main(String args[]) {
  ClientSingletonDoubleLocking clientSingletonDoubleLocking = new ClientSingletonDoubleLocking();
  int length = 5;
  Thread[] thread = new Thread[length];
  
  for (int index = 0; index < length; index++) {
   thread[index] = new Thread(clientSingletonDoubleLocking);
  }
  
  for (int index = 0; index < length; index++) {
   thread[index].start();
  }
 }

 @Override
 public void run() {
  SingletonDoubleLocking singletonDoubleLocking = SingletonDoubleLocking
    .getSingletonDoubleLocking();
 }
}


Output
Object is null
SingletonDoubleLocking - com.doubleLock.SingletonDoubleLocking@18a992f
SingletonDoubleLocking - com.doubleLock.SingletonDoubleLocking@18a992f
SingletonDoubleLocking - com.doubleLock.SingletonDoubleLocking@18a992f
SingletonDoubleLocking - com.doubleLock.SingletonDoubleLocking@18a992f
SingletonDoubleLocking - com.doubleLock.SingletonDoubleLocking@18a992f

As shown above inside a null check it enters only once even though the 5 threads have been started.

In order to check how cloning works put this blok of code in the client file run method and run the file again.
try {
   SingletonDoubleLocking singletonDoubleLocking2 = (SingletonDoubleLocking) singletonDoubleLocking.clone();
  } catch (CloneNotSupportedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }






3 comments:

  1. I'm at a loss to understand how this is a double locked singleton. What's demonstrated above is a singleton no doubt but in order for it to be double locked it would required two null checks on the private singleton instance, one outside a synchronised block to avoid unnecessary locking (once the object has been instantiated) and one inside a synchronised block to avoid the potential race condition, in that order.

    This seems to be a perfectly valid vanilla singleton only and that needn't be a bad thing as described in this post http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    ReplyDelete
  2. I'm at a loss to understand how this is a double locked singleton. What's demonstrated above is a singleton no doubt but in order for it to be double locked it would required two null checks on the private singleton instance, one outside a synchronised block to avoid unnecessary locking (once the object has been instantiated) and one inside a synchronised block to avoid the potential race condition, in that order.

    This seems to be a perfectly valid vanilla singleton only and that needn't be a bad thing as described in this post http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    ReplyDelete
  3. I'm at a loss to understand how this is a double locked singleton. What's demonstrated above is a singleton no doubt but in order for it to be double locked it would required two null checks on the private singleton instance, one outside a synchronised block to avoid unnecessary locking (once the object has been instantiated) and one inside a synchronised block to avoid the potential race condition, in that order.

    This seems to be a perfectly valid vanilla singleton only and that needn't be a bad thing as described in this post http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    ReplyDelete