DCL时需要volatile关键字 [英] Need of volatile keyword in case of DCL

查看:98
本文介绍了DCL时需要volatile关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在实践中阅读并发性。我知道有必要在字段的双重检查锁定机制中使用volatile关键字,否则线程可以读取不是null对象的陈旧值。因为无需使用volatile关键字就可以对指令重新排序。因此,在调用构造函数之前,可以将引用分配给资源变量。所以线程可以看到部分构造的对象。

I was just reading concurrency in practice. I came to know it is necessary to use volatile keyword in double checked locking mechanism for field otherwise thread can read stale value of not null object. Because it is a possibility of reordering instruction without use of volatile keyword. Because of that object reference could be assigned to resource variable before calling constructor. so thread could see partially constructed object.

我对此有疑问。

我认为同步块还限制了编译器对指令的重新排序,因此为什么我们在这里需要volatile关键字?

public class DoubleCheckedLocking {
    private static volatile Resource resource;
    public static Resource getInstance() {
        if (resource == null) {
            synchronized (DoubleCheckedLocking.class) {
                if (resource == null)
                    resource = new Resource();
            }
        }
        return resource;
    }
}


推荐答案

如果调用线程(T1)也从同步块(在同一锁上)读取线程,则JMM仅保证线程T1将在同步块内看到另一个线程T2创建的正确初始化的对象。

The JMM only guarantees that a thread T1 will see a properly initialized object created by another thread T2 inside a synchronized block if the calling thread (T1) also reads it from a synchronized block (on the same lock).

由于T1可以将资源视为非null,因此无需经过同步块即可立即返回资源,因此它可以获取对象,但是看不到其状态正确初始化

Since T1 could see the resource as not null, and thus return it immediately without going though the synchronized block, it could get an object but not see its state properly initialized.

使用volatile可以重新获得保证,因为在volatile字段的写入与该volatile字段的读取之间存在事前发生的关系。

Using volatile brings back that guarantee, because there is a happens-before relationship between the write of a volatile field and the read of that volatile field.

这篇关于DCL时需要volatile关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆