前言:
用在多线程,同步变量。线程为了提高效率,将某个成员(A)变量拷贝了一份(B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步。因此存在A和B不
一致的情况。volatile就是用来避免这个中情况的。volatile告诉jvm,它所修饰的变量不保留拷贝,直接访问主内存中的A。在Java内存模型中,有main memory,每个线程也
有自己的memory(寄存器).为了性能,一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变量在某个瞬时,在一个线程的memory中的值可能与另
一个线程memory中的值,或者main memory中的值不一致的情况。
一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中。
1.特性:
volatile关键字确保了应用中的可视性。如果你将一个域声明为volatile,那么只要这个域产生了写操作,那么所有的读操作都可以看到这个修改。
2. 原子性:
volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但volatile只能让被它修饰的内容具有可见性,但不能保证它具有原子性。
只会影响可见性,不会影响原子性。
3.其他:
1) 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2) 禁止进行指令重排序。
4.实现机制:
观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也
称内存栅栏),内存屏障会提供三个功能:
1) 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已全
部完成。
2) 它会强制将对缓存的修改操作立即写入主存。
3) 如果是写操作,它会导致其他CPU中对应的缓存行无效。
5.通常volatile必须具备以下两个条件:
1) 对变量的写操作不依赖于当前值。
2) 该变量没有包含在具有其他变量的不变式中。
版权声明:本文为博主原创文章,未经博主允许不得转载。