CAS
CAS
是什么?
CompareAndSwap
比较交换,是使用了 unsafe 包下的 native 方法来确保指令得执行是原子的。 这个包在 rt.jar下。
存在的问题---ABA。
识别中间修改的操作不存在
- Thread1和Thread2都拿到值,都为A
- Thread2把A值更新为B
- 此时,Thread1还在处理自己的业务逻辑,然后Thread3拿到的值是B,然后又把值更新为A
- 此时,Thread1进行更新操作,发现更新成功了。出现了ABA问题,按理说,Thread1是不能更新值的。
ABA问题的解决
+时间戳
AtomicStampedReference // 这个类就是带版本号的 解决ABA每次 都会比较版本号(stamp)
public boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp) { Pair<V> current = pair; return expectedReference == current.reference && expectedStamp == current.stamp && ((newReference == current.reference && newStamp == current.stamp) || casPair(current, Pair.of(newReference, newStamp))); }
为什么compareAndSet
能保证原子性?
调用 native 方法,比较和交换一起执行。
最终保证原子性是通过,硬件层面的指令,
comxchg
完成的。如果是多核的情况下,就会上锁。LOCK_IF_MP(mutil Processors)