半栈工程师程序员

你真的懂volatile吗

2018-06-04  本文已影响547人  68号小喇叭

写这篇文章的目的,是在交流中发现有的同学对于volatile的happens-before规则并不太清楚,本文针对对于JMM内存模型的原子性、有序性、可见性等概念有一定了解但对于volatile理解有些模糊的同学,大约花费7分钟左右时间

由一个问题开始:ReentrantLock是如何实现与synchronized锁相同的内存可见性语义的?即:synchronized锁内操作的共享变量值修改在锁被释放后能够保证被其他线程立即看到,ReentrantLock锁能够保证吗,是如何保证的?

当然能够保证,否则就谈不上是同步锁,如何保证的正是本文要谈的内容

误区:有些同学认为volatile修饰的共享变量写操作仅保证当前变量的内存可见性,刷新当前变量所在缓存行回内存,同时由缓存一致性协议invalid其他缓存

几个必要的名次解释

class ReorderExample {  
    int a = 0;  
    boolean flag = false;  
  
    public void writer() {  
        a = 1;          // 1  
        flag = true;    // 2  
    }  
  
    public void reader() {  
        if (flag) {            // 3  
            int i = a * a; // 4  
        }  
    }  
}  

总结:多线程乱序情况汇总

为了保证多线程程序执行的正确性,JMM定义了happens-before规则,重排序需要遵守happens-before规则

happens-before规则

volatile底层实现正是借助内存屏障和缓存一致性协议保障了happens-before规则

回到最初的问题,ReentrantLock如何实现锁的内存可见性语义?

class VolatileExample {
  int x = 0;
  volatile boolean v = false;
  public void writer() {
    x = 42;
    v = true;
  }

  public void reader() {
    if (v == true) {
      //uses x - guaranteed to see 42.
    }
  }
}
上一篇 下一篇

猜你喜欢

热点阅读