java 中的volatile

本博客摘录自   http://www.infoq.com/cn/articles/java-memory-model-4/

 

当我们声明共享变量为volatile后,对这个变量的读/写将会很特别。理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个监视器锁对这些单个读/写操作做了同步。下面我们通过具体的示例来说明,请看下面的示例代码:

 1 class VolatileFeaturesExample {
 2     volatile long vl = 0L;  //使用volatile声明64位的long型变量
 3 
 4     public void set(long l) {
 5         vl = l;   //单个volatile变量的写
 6     }
 7 
 8     public void getAndIncrement () {
 9         vl++;    //复合(多个)volatile变量的读/写
10     }
11 
12 
13     public long get() {
14         return vl;   //单个volatile变量的读
15     }
16 }

假设有多个线程分别调用上面程序的三个方法,这个程序在语意上和下面程序等价:

 1 class VolatileFeaturesExample {
 2     long vl = 0L;               // 64位的long型普通变量
 3 
 4     public synchronized void set(long l) {     //对单个的普通 变量的写用同一个监视器同步
 5         vl = l;
 6     }
 7 
 8     public void getAndIncrement () { //普通方法调用
 9         long temp = get();           //调用已同步的读方法
10         temp += 1L;                  //普通写操作
11         set(temp);                   //调用已同步的写方法
12     }
13     public synchronized long get() { 
14     //对单个的普通变量的读用同一个监视器同步
15         return vl;
16     }
17 }

如上面示例程序所示,对一个volatile变量的单个读/写操作,与对一个普通变量的读/写操作使用同一个监视器锁来同步,它们之间的执行效果相同。

监视器锁的happens-before规则保证释放监视器和获取监视器的两个线程之间的内存可见性,这意味着对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。

posted @ 2016-05-26 16:52  蚂蚁1  阅读(159)  评论(0编辑  收藏  举报