相关疑难解决方法(0)

使用双重检查锁定实现单例时,我们是否需要 volatile

假设我们使用双重检查锁来实现单例模式:

    private static Singleton instance;

    private static Object lock = new Object();

    public static Singleton getInstance() {
        if(instance == null) {
            synchronized (lock) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

Run Code Online (Sandbox Code Playgroud)

我们是否需要将变量“instance”设置为“volatile”?我听到有人说我们需要它来禁用重新排序:

创建对象时,可能会发生重新排序:

address=alloc
instance=someAddress
init(someAddress)
Run Code Online (Sandbox Code Playgroud)

他们说如果最后两个步骤被重新排序,我们需要一个 volatile 实例来禁用重新排序,否则其他线程可能会得到一个没有完全初始化的对象。

然而,既然我们在一个同步代码块中,我们真的需要 volatile 吗?或者一般来说,我可以说同步块可以保证共享变量对其他线程是透明的,即使它不是 volatile 变量也不会重新排序吗?

java singleton volatile synchronized

3
推荐指数
1
解决办法
229
查看次数

在 volatile 环境下分析 JIT 生成的 x86 输出

我写这篇文章是为了深入理解 Java 中的 volatile

public class Main {
    private int x;
    private volatile int g;


    public void actor1(){
       x = 1;
       g = 1;
    }


    public void actor2(){
       put_on_screen_without_sync(g);
       put_on_screen_without_sync(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我正在分析 JIT 为上述代码生成的内容。从我们在上一篇文章中的讨论中我们知道输出1, 0是不可能的,因为:


写挥发v的原因,每一个动作a前述v原因,那a之前是可见的(将被刷新到内存)v将是可见的。


   .................(I removed not important body of method).....

  0x00007f42307d9d5e: c7460c01000000     (1) mov       dword ptr [rsi+0ch],1h
                                                ;*putfield x
                                                ; - package.Main::actor1@2 (line 14)

  0x00007f42307d9d65: bf01000000          (2) mov       edi,1h
  0x00007f42307d9d6a: 897e10              (3) mov …
Run Code Online (Sandbox Code Playgroud)

java jvm volatile memory-barriers

2
推荐指数
1
解决办法
278
查看次数

标签 统计

java ×2

volatile ×2

jvm ×1

memory-barriers ×1

singleton ×1

synchronized ×1