首页 > 代码库 > Java volatile keyword
Java volatile keyword
前言:
用在多线程,同步变量。线程为了提高效率,将某个成员(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.特性:
volatilekeyword确保了应用中的可视性。假设你将一个域声明为volatile,那么仅仅要这个域产生了写操作,那么全部的读操作都能够看到这个改动。
2. 原子性:
volatile修饰的变量不同意线程内部缓存和重排序。即直接改动内存。所以对其它线程是可见的。但volatile仅仅能让被它修饰的内容具有可见性,但不能保证它具有原子性。
仅仅会影响可见性,不会影响原子性。
3.其它:
1) 保证了不同线程对这个变量进行操作时的可见性,即一个线程改动了某个变量的值,这新值对其它线程来说是马上可见的。
2) 禁止进行指令重排序。
4.实现机制:
观察增加volatilekeyword和没有增加volatilekeyword时所生成的汇编代码发现,增加volatilekeyword时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也
称内存栅栏)。内存屏障会提供三个功能:
1) 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在运行到内存屏障这句指令时。在它前面的操作已全
部完毕。
2) 它会强制将对缓存的改动操作马上写入主存。
3) 假设是写操作。它会导致其它CPU中相应的缓存行无效。
5.通常volatile必须具备下面两个条件:
1) 对变量的写操作不依赖于当前值。
2) 该变量没有包括在具有其它变量的不变式中。
Java volatile keyword