Double-checked locking and the Singleton

Double-checked locking and the Singleton - description link
double-checked locking and the Singleton - description link
double-checked locking and the Singleton - description link

For singleton pattern, I believe most people can write several implementations, lazy, hungry man, and so on, however small singleton really want to write, write exactly right is not easy.

Examples of single to double check the lock

Here is the realization of a single example, we often use is to double-check the implementation.

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        
    }

    public Singleton getInstance() {
        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();   // error
                }
            }
        }
        return uniqueSingleton;
    }
}  
复制代码

Let's look at how this code works: First, when a thread makes a request, it will first check whether the instance is null, if not directly then return to its contents, thus avoiding resource into the synchronized block it takes. Second, if two threads simultaneously entered if the first judge, then they must be executed in the order of code synchronized block, the first block of code into the thread creates a new instance of Singleton, and follow the threads because if not pass judgment, but does not create redundant instances.

But there is a problem, in some cases, in this way to get Singleton objects, may be wrong.

Recalling the three steps of our new object

  • 1, to allocate memory space

  • 2, initialize the object

  • 3, the object points to the memory space allocated just

However jvm when the instruction optimization occurs where steps 2 and 3 swapped, such as thread 1 after the two layers is null determination, into the new operation, when not initialized object, a returning the address value, the thread 2 when the first judgment is null, because the object has not empty, then return directly to the object. However, when Thread 2 plan to use the Singleton instance, only to find that it has not been initialized, so the error occurred.

solution

For the above problem, there are two solutions

1, the use of volatile primary keywords can not guarantee the execution jvm affect reordering sequential code.

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {
    }

    public Singleton getInstance() {
        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();   // error
                }
            }
        }
        return instance;
    }
}
复制代码

2, single-mode embodiment of a multithreaded environment by inner classes.

public class Singleton {        
    
    private Singleton() {       
    }        
    
    private static class SingletonContainer {        
        private static Singleton instance = new Singleton();        
    }        
    
    public static Singleton getInstance() {        
        return SingletonContainer.instance;        
    }        
} 
复制代码

Follow us

Follow us

Guess you like

Origin juejin.im/post/5dcba693f265da4d270b508f