volatile仅仅能保证变量可见性, 无法保证原子性.
volatile的race condition示例:
public class TestRaceCondition {
private volatile int i = 0;
public void increase() {
i++;
}
public int getValue() {
return i;
}
}
当多线程执行increase方法时, 是否能保证它的值会是线性递增的呢?
答案是否定的.
原因:
这里的increase方法, 执行的操作是i++, 即 i = i + 1;
针对i = i + 1, 在多线程中的运算, 本身需要改变i的值.
如果, 在i已从内存中取到最新值, 但未与1进行运算, 此时其他线程已数次将运算结果赋值给i.
则当前线程结束时, 之前的数次运算结果都将被覆盖.
即, 执行100次increase, 可能结果是 < 100.
一般来说, 这种情况需要较高的压力与并发情况下, 才会出现.
如何避免这种情况?
解决以上问题的方法:
一种是 操作时, 加上同步.
这种方法, 无疑将大大降低程序性能, 且违背了volatile的初衷.
第二种方式是, 使用硬件原语(CAS), 实现非阻塞算法
从CPU原语上, 支持变量级别的低开销同步.
volatile运算存在脏数据问题
最新推荐文章于 2021-02-19 16:51:09 发布