2

Could please explin me in detail about doubly checking singleton..! what are it advantages and disadvantages..!! I have this below class..How could I make it as a doubly checking singleton..

 private DataBaseDAO() { }
        public static synchronized DataBaseDAO getInstance() {
            if (dao == null) {
                dao = new DataBaseDAO();
                }
            return dao;
            }
        }
    }
user1582269
  • 285
  • 1
  • 6
  • 12
  • 1
    see this great post on doubly checking Singletons: http://www.ibm.com/developerworks/java/library/j-dcl/index.html – David Kroukamp Aug 08 '12 at 16:38
  • 1
    The main disadvantage of the double checked locking idiom: it is broken, unless you make dao volatile. Don't use it. – assylias Aug 08 '12 at 16:54

3 Answers3

3

Consider the below code

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {  //1
      if (instance == null)          //2
        instance = new Singleton();  //3
    }
  }
  return instance;
}

The theory behind double-checked locking is that the second check at //2 makes it impossible for two different Singleton objects to be created as occurred in Listing

Consider the following sequence of events:

Thread 1 enters the getInstance() method.

Thread 1 enters the synchronized block at //1 because instance is null.

Thread 1 is preempted by thread 2.

Thread 2 enters the getInstance() method.

Thread 2 attempts to acquire the lock at //1 because instance is still null. However, because thread 1 holds the lock, thread 2 blocks at //1.

Thread 2 is preempted by thread 1.

Thread 1 executes and because instance is still null at //2, creates a Singleton object and assigns its reference to instance.

Thread 1 exits the synchronized block and returns instance from the getInstance() method.

Thread 1 is preempted by thread 2.

Thread 2 acquires the lock at //1 and checks to see if instance is null.

Because instance is non-null, a second Singleton object is not created and the one created by thread 1 is returned.

The theory behind double-checked locking is perfect. Unfortunately, reality is entirely different. The problem with double-checked locking is that there is no guarantee it will work on single or multi-processor machines. The issue of the failure of double-checked locking is not due to implementation bugs in JVMs but to the current Java platform memory model. The memory model allows what is known as "out-of-order writes" and is a prime reason why this idiom fails.

Bhavik Ambani
  • 6,557
  • 14
  • 55
  • 86
3

A good solution, as described in "Effective Java Second Edition", is to use the "Singleton-as-enum" pattern:

public enum DataBaseDAO() {
    INSTANCE;
}

and access it via DataBaseDAO.INSTANCE. This guarantees, in all cases, that there will be one and only one instance of DataBaseDAO.

Andrea Bergia
  • 5,502
  • 1
  • 23
  • 38
0

In your code implementation you are doing static method level synchronization. If there are other static methods in the DatabaseDAO class, then even if the methods can work independently using those methods, they won't be able to. You can avoid this by doing block level synchronization. In multi-threaded application, this is one of the safest way to implement singleton object -

private DataBaseDAO {
    private static final Object lock = new Object();
    private static DataBaseDAO dao = null;
    private DataBaseDAO() { }
    public static DataBaseDAO getInstance() {
        if (dao == null) {
            synchronize(lock) {
               if (dao == null) {
                   dao = new DataBaseDAO();
                }
            }
        }
        return dao;

    }
}

As an object lock you can also use DataBaseDAO.class.

Explanation: Multiple threads access the getInstance() method at the same time. In an interleaved scenario 2 or more threads can pass the first if check, but only one thread will acquire lock on the lock object. The thread that acquires lock will be able to create the instance. Other threads, even though have passed the first if check will not be able to get the lock if the first thread has already acquired it (and first thread has not released it).

Now, say first thread released the lock, which means it has also instantiated the dao object. When other threads are scheduled, each thread will acquire the lock, but the second if check will fail and will release the lock immediately and get the already instantiated dao object.

Once the object is created, later all threads that would try to access the getInstance() method will not be doing any synchronization as the first if itself will fail.

devang
  • 5,376
  • 7
  • 34
  • 49
  • @gotuskar..please explain the use of second line..that is..private static final Object lock = new Object(); .. please explain its functionality – user1582269 Aug 08 '12 at 16:43
  • -1 This is a good example of what you should NOT do. It is a broken design. – assylias Aug 08 '12 at 16:44
  • @user1582269 Check [this post](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java): use an enum. – assylias Aug 08 '12 at 16:47
  • @assylias: Definitely `enum` is one of the safest implementation. Could you explain how is this design broken? – devang Aug 08 '12 at 16:56
  • @gotuskar Your explanation is wrong. It is possible that a thread could see a non null value of dao **before** it has been properly constructed (dao has been assigned a reference but the underlying object is not fully constructed yet). The only way to make it work would be to make dao volatile. – assylias Aug 08 '12 at 16:56
  • See for example: http://stackoverflow.com/questions/157198/double-checked-locking-article and http://stackoverflow.com/questions/7855700/java-why-is-volatile-used-in-this-example-of-double-checked-locking – assylias Aug 08 '12 at 17:00
  • 1
    @assylias: Interesting read. Thank you so much for sharing those links. That definitely has given me a good picture. – devang Aug 08 '12 at 17:30