在Java中使用volatile在单例双null检查实现中 [英] Use of volatile in singleton double null check implementation in java

查看:93
本文介绍了在Java中使用volatile在单例双null检查实现中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道在Singleton的双null检查实现中将Instance变量设置为volatile的用途.因为按照我的理解,同步块提供先于隐式发生.没有两个线程可以同时访问该同步块,并且在从同步块退出时,线程将其所有本地缓存​​的数据写入主内存. 我进行了很多搜索,但仍然对这种实现方式有疑问.请说明正确用法.

I want to know what is use of making Instance variable as volatile in double null check implementation of Singleton. Because as per my understanding synchronize block provide happens before implicitly. No two threads can access that synchronized block concurrently and while exiting from synchronized block, thread write all its local cached data to main memory. I search a lot but still i have doubts in this implementation. Please explain correct use.

private volatile Singleton INSTANCE; 
public Singleton get() { 
    if (INSTANCE == null) { 
        synchronized (this) { 
            if (INSTANCE == null) { 
                INSTANCE = new Singleton(); 
            } 
        } 
    } 
    return INSTANCE; 
}

在上面的双重检查代码中.如果我不使实例具有可变性,可能会出现什么问题?因为当第一个线程进入同步块时,其他线程将无法访问该块.当第一个线程离开该块时.对象将被创建,并且由于发生在属性之前,实例的最新值将被写入主存储器.那么为什么在这种情况下挥发物很重要?

In above double checking code. What may b the issue if i dont make my instance as volatile. Because when first thread enter in synchronize block, no other thread will get access to that block. And when first thread leaves that block. Object will be created and due to happens before property, latest value of instance will be written in main memory. So why volatile is important in this scenario?

这是一个链接(

Here's a link (Is there any need to add volatile keyword to guarantee thread-safe singleton class in java?) of similar question. But answers are not very clear. I don't think in above given scenario any kind of JVM optimization can cause breaking of happens before of synchronize block

推荐答案

volatile在这里很重要,因为JVM在字节码级别上是内部的.声明

volatile is important here because of the internals of the JVM on the bytecode level. The statement

INSTANCE = new Singleton()

在字节码级别实际上是这样的:

is on bytecode level actually something like that:

1. INSTANCE = create Singleton object
2. call constructor of INSTANCE

如果INSTANCE为volatile,则JVM保证从其他线程的角度来看,将1 + 2作为原子操作执行.通过将实例存储在堆栈上,然后再将其存储在字段中.如果不是 volatile,则可能是其他线程可以在调用构造函数之前已经看到对Singleton的引用.因此,这些线程可能会看到不完整的对象.

if INSTANCE is volatile the JVM guarantees you that 1+2 are executed as an atomic operation from the point of view of other threads, e.g. by storing the instance on the stack before storing it in the field. If it is not volatile it might be that other threads can already see the reference to Singleton before the constructor has been called. Thus these threads might see an incomplete object.

这篇关于在Java中使用volatile在单例双null检查实现中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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