volatile的特性
理解volatile特性的一个好方法是把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步。下面通过具体的实列来说明:
class VolatileFeaturesExample{
volatile long v1=0L;
//单个volatile变量的写
public void set(long l){
v1=l;
}
//多个操作,整体不具备原子性
public void getAndIncrement(){
v1++;
}
//单个volatile变量的读
public long get(){
return v1;
}
}
class VolatileFeaturesExample{
long v1=0L;
//上锁
public synchronized void set(long l){
v1=l;
}
//多个操作,整体不具备原子性
public void getAndIncrement(){
v1++;
}
//上锁
public synchronized long get(){
return v1;
}
}
如上面示例程序所示,一个volatile变量的单个读/写操作,与一个普通变量的读/写操作都是使用同一个锁来同步,它们之间的执行效果相同。
锁的happens-before规则保证释放锁和获取锁的两个线程之间的内存可见性,这意味着对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
锁的语义决定了临界区代码的执行具有原子性,对该变量的读/写就具有原子性。这意味着,即使64位的long型和double型变量,只要他是volatile变量,对该变量的读/写就具有原子性。如果是多个volatile操作或类式于volatile++这钟复合操作,这些操作整体上不具有原子性。
简而言之,volatile变量自身具有以下特性:
可见性:读一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入
原子性: 对任意单个volatile变量的读/写具有原子性,但类式于volatile++这种复合操作不具有原子性
以上内容摘抄于《Java并发编程艺术》