Volatile

Volatile

Volatile关键词有什么作用?

1.内存可见性;
2.禁止指令重排序。

换个思路:
redis应该大部分人都用过,当一个查询很频繁的时候,可以把数据缓存到redis,
这样查询直接走缓存,不查数据库了。

当你修改了数据库记录后,会造成与redis中的数据不一致,这就需要在你修改
数据库的同时,要么同时更新缓存,要么直接把缓存清空,下次查询会自动同步缓存。

再来看看volatile:
cpu正常情况下不和内存交互而是和高速缓存打交道,这里内存就相当于宏观上的数据库,
高速缓存就相当于宏观上的redis。

 

 

Volatile关键词的语义分析

volatile作用:让其他线程能够马上感知到某一线程多某个变量的修改

(1)保证可见性

对共享变量的修改,其他的线程马上能感知到

不能保证原子性  读、写、(i++)

(2)保证有序性

重排序(编译阶段、指令优化阶段)

输入程序的代码顺序并不是实际执行的顺序

重排序后对单线程没有影响,对多线程有影响

 

 

Volatile的使用场景

(1)状态标志(开关模式)

public class ShutDowsnDemmo extends Thread{

    private volatile boolean started=false;

 

    @Override

    public void run() {

        while(started){

            dowork();

        }

    }

    public void shutdown(){

        started=false;

    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(2)双重检查锁定(double-checked-locking)

public class Singleton {

    private volatile static Singleton instance;

    public static Singleton getInstance(){

        if(instance==null){

            synchronized (Singleton.class){

                instance=new Singleton();

            }

        }

        return instance;

    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Volatile和synchronized的区别

(1)使用上的区别

Volatile只能修饰变量,synchronized只能修饰方法和语句块

(2)对原子性的保证

synchronized可以保证原子性,Volatile不能保证原子性

(3)对可见性的保证

都可以保证可见性,但实现原理不同

Volatile对变量加了lock,synchronized使用monitorEnter和monitorexit  monitor  JVM

(4)对有序性的保证

Volatile能保证有序,synchronized可以保证有序性,但是代价(重量级)并发退化到串行

(5)其他

synchronized引起阻塞

Volatile不会引起阻塞

 

 

Volatile的使用限制

由于volatile变量只能保证可见性,在不符合以下两条规则的运算场景中,我们仍然要通过加锁(使用synchronized或java.util.concurrent中的原子类)来保证原子性。

  • 运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
  • 变量不需要与其他的状态变量共同参与不变约束。

 

posted @ 2020-02-02 23:13  Kanggood  阅读(109)  评论(0编辑  收藏  举报