javalockingdouble-checked-locking

Java double checked locking code explanation


I have a code snippet that I don't understand I will highlight the bit that confused me.

private static final Object lock = new Object();
private static volatile YourObject instance;

public static YourObject getInstance() {
    YourObject r = instance;    // <---------- This bit, why do we assign it here ? 
    if (r == null) {
        synchronized (lock) {    // What is the benefit of this lock in here
            r = instance;        // assuming instance is null which will pass the first if ( r == null, what do we assign it again ?? I don't get the idea of this step at all. 
            if (r == null) {  
                r = new YourObject();
                instance = r;
            }
        }
    }
    return r;
}

I have seen https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples but there implementation looks like this, which doesn't have two assignments.

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

Solution

  •     YourObject r = instance;    // <---------- This bit, why do we assign it here ?
    

    It is easier to reason about local variables, which you really want here. Also there is overhead in reading volatile variables that may not be merged by the optimiser.

        synchronized (lock) {    // What is the benefit of this lock in here
    

    This is the lock that prevents multiple threads creating and assigning different instances of YourObject simultaneously.

            r = instance;        // assuming instance is null which will pass the first if ( r == null, what do we assign it again ?? I don't get the idea of this step at all. 
    

    instance may have changed between the first read for the null check and the lock being successfully acquired.

    Anyway, don't use double-checked locking - it's very confusing and there's probably better ways.