由于隐式内存屏障,双重检查锁定不是问题?

Double checked locking not a concern because of implicit memory barrier?

我正在审查一段代码并注意到用于设置会话锁的双重检查锁定实现:

Lock lock = getLock(mySession);
if (lock == null) {
    synchronized (myService.class) {
        lock = getLock(mySession);
        if (lock == null) {
            lock = new ReentrantLock();
            setLock(mySession, lock);
        }
    }
}

与此代码片段一起有一条评论说开发人员假设该属性存在内存屏障:CPU 将刷新其缓存并直接从主内存读取值。

这是一个很好的假设,还是最好的做法仍然是将 'lock' 定义为 volatile 以保证它?

假设您的代码是块或方法范围的:

public void mymethod() {
//...
Lock lock = getLock(mySession);
if (lock == null) {
    synchronized (myService.class) {
        lock = getLock(mySession);
        if (lock == null) {
            lock = new ReentrantLock();
            setLock(mySession, lock);
        }
    }
}
//...
}

双重检查问题根本不适用于它,因为lock是一个局部变量(分配在线程的堆栈上),所以每个线程都看到它自己的副本,并且没有并发访问它(这是双重检查问题的必要前提)。