1600 PMP mock questions 1400 CAPM mock questions 800 SCJP 6 mock questions 600 OCAJP 7 mock questions 590 OCPJP 7 mock questions 556 SCWCD 5 mock questions 500 OCEJWCD 6 mock questions pdfDownload (java,struts, hibernet etc)

Java Tutorials

Sigleton Double check locking.

To understand where the double-checked locking idiom originated, you must understand the common singleton creation idiom, which is illustrated in Listing 1:


Listing 1. Singleton creation idiom


import java.util.*;
class Singleton
{
private static Singleton instance;
private Vector v;
private boolean inUse;

private Singleton()
{
v = new Vector();
v.addElement(new Object());
inUse = true;
}

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



The design of this class ensures that only one Singleton object is ever created. The constructor is declared private and the getInstance() method creates only one object. This implementation is fine for a single-threaded program. However, when multiple threads are introduced, you must protect the getInstance() method through synchronization. If the getInstance() method is not protected, it is possible to return two different instances of the Singleton object. Consider two threads calling the getInstance() method concurrently and the following sequence of events:

Thread 1 calls the getInstance() method and determines that instance is null at //1.


Thread 1 enters the if block, but is preempted by thread 2 before executing the line at //2.


Thread 2 calls the getInstance() method and determines that instance is null at //1.


Thread 2 enters the if block and creates a new Singleton object and assigns the variable instance to this new object at //2.


Thread 2 returns the Singleton object reference at //3.


Thread 2 is preempted by thread 1.


Thread 1 starts where it left off and executes line //2 which results in another Singleton object being created.


Thread 1 returns this object at //3.
The result is that the getInstance() method created two Singleton objects when it was supposed to create only one. This problem is corrected by synchronizing the getInstance() method to allow only one thread to execute the code at a time, as shown in Listing 2:


Listing 2. Thread-safe getInstance() method


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



The code in Listing 2 works fine for multithreaded access to the getInstance() method. However, when you analyze it you realize that synchronization is required only for the first invocation of the method. Subsequent invocations do not require synchronization because the first invocation is the only invocation that executes the code at //2, which is the only line that requires synchronization. All other invocations determine that instance is non-null and return it. Multiple threads can safely execute concurrently on all invocations except the first. However, because the method is synchronized, you pay the cost of synchronization for every invocation of the method, even though it is only required on the first invocation.

In an effort to make this method more efficient, an idiom called double-checked locking was created. The idea is to avoid the costly synchronization for all invocations of the method except the first. The cost of synchronization differs from JVM to JVM. In the early days, the cost could be quite high. As more advanced JVMs have emerged, the cost of synchronization has decreased, but there is still a performance penalty for entering and leaving a synchronized method or block. Regardless of the advancements in JVM technology, programmers never want to waste processing time unnecessarily.

Because only line //2 in Listing 2 requires synchronization, we could just wrap it in a synchronized block, as shown in Listing 3:


Listing 3. The getInstance() method


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



The code in Listing 3 exhibits the same problem as demonstrated with multiple threads and Listing 1. Two threads can get inside of the if statement concurrently when instance is null. Then, one thread enters the synchronized block to initialize instance, while the other is blocked. When the first thread exits the synchronized block, the waiting thread enters and creates another Singleton object. Note that when the second thread enters the synchronized block, it does not check to see if instance is non-null.




Back to top




Double-checked locking

To fix the problem in Listing 3, we need a second check of instance. Thus, the name "double-checked locking." Applying the double-checked locking idiom to Listing 3 results in Listing 4.


Listing 4. Double-checked locking example


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 3. 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.

Reviews and Comments


PMP, CAPM, PMI is a registered certification mark of the Project Management Institute, Inc

Copyright © www.techfaq360.com 2016


About US | Contact US | Privacy Policy | Terms and Conditions  | Website disclaimer  | Cancellation and Refund Policy  | Shipping & Delivery Policy