volatile

来源:互联网 发布:怎么测试网络稳定性 编辑:程序博客网 时间:2024/06/15 08:19

volatile关键字能够保证变量的可见性,这就先要了解Java内存模型,Java内存模型是所有线程有一个共享的主内存,每个线程都有自己的工作内存,工作内存里都会保存一份共享变量的副本,对变量修改都是修改本线程的变量副本,然后刷新到主内存,但是刷新的时间是不确定的。volatile修饰了变量之后,每个线程修改变量副本之后都会立即刷新到主内存,读取这个变量也会强制从主内存读取最新值。所以volatile保证了变量的可见性。

1,在什么场景下能够使用volatile保证线程安全?

因为volatile能够保证可见性,有序性,不能保证原子性,所以在保证原子性的场景下使用volatile能实现线程安全。符合下面两条规则的场景:

1,运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。

2,变量不需要与其他的状态变量共同参与不变约束。

否则要使用synchronized,Lock,原子类来保证原子性。因为锁保证了原子性,可见性,有序性,所以是线程安全的。


2,虚拟机层面是如何保证立即可见的呢?

对volatile修饰的变量赋值后,多执行了一个带lock前缀的空操作,这个操作相当于一个内存屏障,内存屏障能够在多个CPU访问同一块内存时保证一致性。lock前缀的作用是使得本CPU的Cache写入了内存,该写入动作也会引起别的CPU或者别的内核无效化其Cache,这种操作相当于对Cache中的变量做了一次“store”“write”操作,将变量从工作内存同步回主内存,所以通过这样一个空操作,可以让volatile变量的修改对其他CPU立即可见。

3,如何保证有序性的呢?

volatile本身具有禁止指令重排序语义,因为指令重排序无法越过内存屏障。


原创粉丝点击