看个例子,仅是个人理解。
public class VolatileDemo { public static volatile int count; public static void main(String[] args) { count++; } }当进行自增操作,字节码是这样的
1、获取变量的值并入栈
2、把1入栈
3、依次取出栈中两个操作数相加并入栈(假设为临时变量t)
4、取出栈顶值赋值给变量
而volatile的可见性指的是第4步,当修改变量后,把新值刷新到内存,并使其他线程使用此变量的的缓存行失效(多核处理器),那么会重新读取变量的值,即缓存一致性;但是如果其他线程已经已经进行到了第3步,那么意味着仅仅是重新读了一遍新的变量值,会直接将已经计算好的t赋值给变量。
public class VolatileDemo { public static volatile int count; public static int a = 1; public static void main(String[] args) { count = a; } }而当自增操作变成这样的,字节码是这样的
1、获取a的值并压入栈
2、取出栈顶元素赋值给count
这样的话即使第一步被其他线程打断,并且a的值被修改,那也是重新获取一遍,并赋给count,不会存在安全问题。
所以看来volatile不会保证(i++)这样复合操作的原子性。