CAS概念:
CAS全称Compare And Swap,中文是对比并交换,是乐观锁的一种,是说多线程之一在写入修改值前先判定内存位置V中的值是否是预期值,是则修改V中的值,否则获取V中的值重复CAS。
CAS的过程是:(1) 线程读取内存位置V中当前值E到线程内部,然后修改E,写回内存前再次获取位置V的值,假如是N,判断N\==E?,如果N\==E,说明没有其他线程修改位置V的值,执行写回操作。CAS流程图如下(来自马士兵老师公开课程)
ABA问题
ABA是:如果线程1第二次获取位置V处的值依旧是E,但是这个E应不是一开始的E了,它可能被线程2变换了两次,举个例子就是E-> X -> E,但是线程1并不知道,然后修改了内存V的值,这个过程就发生了ABA问题。ABA问题的解决方式可以利用版本号或者时间戳。相关类有 AtomicStampedReference.
CAS原理
CAS是使用JDK类UnSafe实现的,UnSafe类是使用C++代码实现的,往更底层来讲,是通过汇编代码实现的。
Unsafe类中对应的代码是:
1 | inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { |
关键在于:(LOCK_IF_MP(%4)) “cmpxchgl %1,(%3)”。
这说明CAS的底层实现还是依靠汇编指令cmpxchg
LOCK_IF_MP是说:如果多线程(MP=Multi Processor),则需要在汇编命令cmpxchg前加上lock
因此,关键指令就是lock cmpxchg
lock指令可以保证线程执行CAS的过程不受干扰,即加上锁,避免线程写回内存过程位置V处的值发生改变。
lock的硬件原理是:lock指令在执行后面指令的时候锁定一个北桥信号,网上也说是锁内存总线或者cache,这部分去网上翻了翻,大致找到了以下几个资料:
感谢马老师。