volatile的特性:java
对单个变量的读/写能够当作锁对单个变量所作的同步。jvm
class VolatileFeaturesExample { volatile long vl = 0L; // 使用volatile声明64位的long型变量 public void set(long l) { vl = l; // 单个volatile变量的写 } public void getAndIncrement () { vl++; // 复合(多个)volatile变量的读/写 } public long get() { return vl; // 单个volatile变量的读 } }
class VolatileFeaturesExample { long vl = 0L; // 64位的long型普通变量 public synchronized void set(long l) { // 对单个的普通变量的写用同一个锁同步 vl = l; } public void getAndIncrement () { // 普通方法调用 long temp = get(); // 调用已同步的读方法 temp += 1L; // 普通写操做 set(temp); // 调用已同步的写方法 } public synchronized long get() { // 对单个的普通变量的读用同一个锁同步 return vl; } }
可见性。对一个volatile变量的读,老是能看到(任意线程)对这个volatile变量最后的写入。优化
原子性:对任意单个volatile变量的读/写具备原子性,但相似于volatile++这种复合操做不具备原子性。线程
volatile写/读的内存语义:code
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。内存
经过把写线程修改的结果写入主存中,设置其余线程本地内存包含的值设置为无效,所以其余线程须要从新从主存读取来保证数据的一致性。rem
对volatile变量写入与读取的过程,形式上相似线程间的通讯。get
sychronized:编译器
锁释放与volatile写有相同的内存语义,锁获取与volatile读有相同的内存语义。同步
sychronized与volatile区别: