首页 > 解决方案 > JVM在使用synchronized时如何保证被引用对象中成员变量修改的可见性?

问题描述

我想知道JVM在使用同步时如何保证被引用对象中成员变量修改的可见性。

我知道 synchronized 和 volatile 将为变量修改提供可见性。

class Test{
    public int a=0;

    public void modify(){
        a+=1;
    }
}


//Example:

// Thread A:
 volatile Test test=new Test();
 synchronized(locker){
   test.modify();
 }

// then thread B:
synchronized(locker){
   test.modify();
}

// Now, I think test.a==2 is true. Is it ok? How JVM implements it?
// I know the memory barrier, does it flush all cache to main storage?

线程 A 先在一个块中调用 modify sychronized,然后将对象传递给线程 B(将引用写入volatile变量。)。然后线程 B 再次调用 modify(在 中synchronized)。

a==2 有什么保证吗?JVM是如何实现的?

标签: javajvm

解决方案


线程之间的可见性通过Memory Barriers/Fences强制执行。在synchronized块的情况下,JVM 将在块执行完成后插入内存屏障。

JVM 使用 CPU 指令实现内存屏障,例如使用x86上的指令完成存储屏障sfence和使用指令完成加载屏障。lfence还有mfence可能特定于 CPU 架构的其他指令。


推荐阅读