Dual-check locking and delayed initialization in Java multithreading concurrency __java

Source: Internet
Author: User
Tags static class volatile
double check locking and delay initialization

In Java multithreaded programs, it is sometimes necessary to adopt lazy initialization to reduce the overhead of initializing classes and creating objects. Double check locking is a common technique for delaying initialization.
Let's look at an example of a non thread-safe lazy Initialization object:

public class Singleton {
    private static Singleton instance;
    public static Singleton getinstance () {
        if (instance = null)//1: A thread execution
            instance = new Singleton ();//2:b Thread execution 
  return instance
    }
}

If a thread executes code 1, the B thread executes code 2. At this point, thread A may see that the object referenced by instance has not finished initializing
Let's change the code above to make it thread safe.

public class Singleton {
    private static Singleton instance;
    public static synchronized Singleton getinstance () {
        if (instance = = NULL)//1: A thread execution
            instance = new Singleton () ; 2:b Thread execution return
        instance
    }
}

Because the getinstance () method is synchronized, synchronized results in performance overhead. If the getinstance () method is called frequently by multiple threads, it will result in a drop in performance of the program (usually the single example provided in our project is always called frequently). Conversely, if the getinstance () method is not frequently invoked by multiple threads, the deferred initialization scheme will provide satisfactory performance.
Below we further reduce the overhead of synchronization by double check locking, as follows:

public class Singleton {
    private static Singleton instance;
    public static Singleton getinstance () {
        //first check
        if (instance = null) {
            //Lock
            synchronized ( Singleton.class) {
                if (instance = = NULL) 
                    //Allocate memory space, initialize object, instance point to allocated memory address
                    instance = new Singleton (); 
            }
        }
        return instance
    }
}

Does the code above really guarantee a single example? Let's analyze it.
As the code above shows, if the first check instance is not NULL, then you do not need to perform the following lock and initialization operations. Therefore, the performance overhead of synchronized can be greatly reduced. The code above appears to have both worlds. When multiple threads attempt to create an object at the same time, a lock is added to ensure that only one line Cheng Nen the object. After the object is created, executing the getinstance () method will not need to acquire the lock and directly return the created object. The double check lock looks perfect, but it's a mistake to optimize. When the code reads to instance is not NULL, the object referenced by instance may not have completed initialization.
Let's continue the analysis.
The previous double check Lock sample code (instance=new Singleton ()) creates an object. This line of code can be decomposed into the following 3 lines of pseudo code.

Memory = allocate ();  1: Allocating the object's memory space
ctorinstance (memory);//2: Initializing object
instance = memory; 3: Set instance point to the memory address just allocated

3 lines of pseudo code between 2 and 3, may be reordered by reordering between 2 and 3 after the execution sequence follows.

Memory = allocate ();  1: Allocating the object's memory space
instance = memory; 3: Set the instance point to the memory address you just allocated; Note that the object is not initialized at this time.
ctorinstance (memory);//2: Initializing Object

Now let's take a look at the implementation of multithreaded concurrency


Because the intra-thread semantics is adhered to in a single thread, it guarantees that the execution of a thread will not be changed. However, when threads A and B are executed in Figure 3-38, the B thread will see an object that has not yet been initialized.
Based on the above problem, we have 2 solutions
1, do not allow 2 and 3 reordering
2, allow 2 and 3 reordering, but do not allow other threads to "see" this reordering
Solution one: Based on volatile solution

Only the previous delay scheme based on double check locking is needed to change the instance to volatile (JDK1.5 above support)

public class Singleton {
    private static volatile Singleton instance;
    public static Singleton getinstance () {
        //first check
        if (instance = null) {
            //Lock
            synchronized ( Singleton.class) {
                if (instance = = NULL) 
                    //Allocate memory space, initialize object, instance point to allocated memory address
                    instance = new Singleton (); 
            }
        }
        return instance
    }
}

When declared as volatile, the 2 and 3 rearrangement will be disabled, and the code will execute in the following order

Scenario Two: A solution based on class initialization
The JVM performs initialization of the class during the initialization phase of the class (that is, before class is loaded and before it is used by the thread). During initialization of the class, the JVM acquires a lock. This lock can synchronize multiple threads to initialize the same class. Based on this feature, another thread-safe delay initialization scheme can be implemented

public class Singleton {
    private static class Instanceholder {public
        static Singleton instance = new Singleton ();
    }
    The public static Singleton getinstance () {
        //will cause the Instanceholder class to be initialized to return
        instanceholder.instance;
    }

Assuming two threads execute the getinstance () method concurrently, the following is a schematic of the execution

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: [email protected] and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.