Java 仔细检查锁定代码解释

Java double checked locking code explanation

我有一个我不明白的代码片段,我会突出显示让我困惑的部分。

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;
}

我看过 https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples,但是实现看起来像这样,没有两个赋值。

public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
    if(instance == null){
        synchronized (ThreadSafeSingleton.class) {
            if(instance == null){
                instance = new ThreadSafeSingleton();
            }
        }
    }
    return instance;
}
    YourObject r = instance;    // <---------- This bit, why do we assign it here ?

这里更容易推理出你真正想要的局部变量。读取优化器可能不会合并的 volatile 变量也有开销。

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

这是防止多个线程同时创建和分配 YourObject 的不同实例的锁。

        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 可能在 null 检查的第一次读取和成功获取锁之间发生了变化。

无论如何,不​​要使用 double-checked 锁定 - 这非常令人困惑,可能有更好的方法。