Single case mode and double check lock DCL

Source: Internet
Author: User
Tags prepare volatile

It's about design patterns that remind you of an interview you've been through. At that time, I told the single case mode, but did not fully understand the thread-safety problem related to the single case pattern, then the scene, hey, past memories, but technology, after all, it is necessary to master drops ~

1. Single Case mode

About the single case mode, no longer detailed description, presumably everyone is familiar with, a simple review. Here is an example of a single example pattern:

public class Doublecheckedlock {
    private static doublecheckedlock instance;  
	  
    public static Doublecheckedlock getinstance () {  
        if (instance = null) {  
        	instance=new doublecheckedlock ();
        } Return  
        instance  
    }  
}

The above example, if in the case of concurrency, will encounter serious problems. For example, when a thread A in the judge instance is empty, enters the new operation, the new operation has not finished, at this time thread B also runs to judge whether instance is null, then may cause the thread A and the thread B all in new, that violates the single example pattern the original meaning. So since we need to ensure that there is only one instance, can we solve it by synchronized keyword.

public class Doublecheckedlock {
    private static doublecheckedlock instance;  
	  
    public static synchronized Doublecheckedlock getinstance () {  
        if (instance = = null) {  
        	instance=new Doublecheckedlock ();
        }  
        return instance  
    }  
}

Admittedly, the Synchronized keyword is guaranteed to be a single case, but the performance of the program is not optimistic, because getinstance () the entire method body is synchronized, which limits the access speed. The only thing we need is synchronization when we first initialize the object, and we don't need to sync the lock for subsequent gain. As a result, further improvements can be made:

public class Doublecheckedlock {
    private static doublecheckedlock instance;  
	  
    public static Doublecheckedlock getinstance () {  
        if (instance = null) {  //STEP1
        	synchronized ( Doublecheckedlock.class) {//step2
        		if (instance==null) {//step3
        			instance=new doublecheckedlock ();//step4
        		}
        	}
        }  
        return instance  
    }  
}

This reduces the locking granularity to just the part where the instance is initialized, so that the code is correct and the execution efficiency is guaranteed. This is called the "double check lock" mechanism (as the name suggests).

The emergence of double check-lock mechanism is really to solve the multithreading in parallel does not appear duplicate new object, but also to achieve lazy loading, but unfortunately, such a writing on many platforms and optimization compiler is wrong , because: instance=new Doublecheckedlock () The behavior of this line of code on different compilers is unpredictable. An optimization compiler can legitimately implement the following Instance=new Doublecheckedlock ():

1. Allocating memory to the new entity instance;

2. Invoke the Doublecheckedlock constructor to initialize the instance.

Now imagine that threads A and b are called Doublecheckedlock, thread A enters first, and is kicked out of the CPU when it executes to step 4. Then thread B enters, and b sees that instance is not NULL (memory has been allocated), so it begins to use instance confidently, but this is wrong, because a has not had time to complete the initialization of instance, Thread B Returns a instance instance that has not been initialized.

When we combine the Java Virtual machine class loading process will be better understood. I'm not quite familiar with the JVM loading class process, so I'll briefly introduce:

The JVM loading a class is generally divided into three steps:
1 Loading phase: It is on the hard disk to find the corresponding class file Java file, and the class file in the binary data loaded into memory, put it in the Run-time data area in the method area, A Java.lang.Class object is then created in the heap area to encapsulate the data structure within the method area;
2 Connection phase: This phase is divided into three steps, step one: Verify, of course, verify that the binary data in this class file conforms to the Java specification; Step two: Prepare, allocate the memory space for the static variable of the class, and assign the variable a default value, for example, the default value of int is 0; step three: Parse, This stage is difficult to explain, the symbolic reference into a direct reference, involving pointers;
3 Initialization phase: When we actively invoke the class, assign the class variable to the correct value (not to be confused with the second stage of preparation), and give an example of the next two differences, such as a class with private static int i = 5; This static variable is assigned a memory space in the "prepare" phase and is given a default value of 0, which is given the correct value of 5 when the initialization phase is known.

Therefore, double check locks apply to the underlying type, such as Int. Because the underlying type does not call the constructor this step. So for the problem that the compiler optimization cannot guarantee the execution order in the double check lock, specifically, in C + + the compiler for a streamlined instruction set (RISC) machine rearranges the compiler-generated assembly language instructions, allowing the code to optimally use the parallel characteristics of the RISC processor, and thus potentially damaging the dual-check lock mode. For this issue, a number of consulting solutions, mainly the following:

1 Use Memory Barrier, merrory barrier introduction, can refer to the Bowen "Memory barrier".

2 Java can consider volatile keyword definition of new semantics to solve this problem, the use of volatile keyword, visible bowen "volatile keyword."









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: info-contact@alibabacloud.com 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.