其他分享
首页 > 其他分享> > CAS的底层剖析

CAS的底层剖析

作者:互联网

CAS

 

 

 

1、什么是CAS?

CAS:又叫 campare and set/Swap/Exchange;

 

 

ABA 问题的解决办法:加版本号。如,每改变一次,自身版本号就 加1。而是否对最后结果有影响(是否更新为新值)需要程序员自己判断。

如果程序员觉得没什么影响,只要结果还是A那就行,如果程序员觉得如果有改变,心里膈应,那就不行。

 

2、使用原子类的底层实现原理

以AtomicInteger 为例:

代码如下,为了实现线程安全,我们使用了原子类AtomicInteger ,而且变量增加使用了AtomicInteger 类的类方法 incrementAndGet()。

 

 

 接下来我们就对incrementAndGet() 一探究竟。

按住ctrl + 单击该方法,跳转到AtomicInteger.java类中:

 

 

 再点进去unsafe.getAndAddInt()方法,跳转到unsafe.class类中:

 

 

 这里有一个循环,条件是做一个CAS 操作。再点击进去,找到是当前类的一个native方法。

 

 

 这是什么意思呢?native表示这是用C/C++写的底层代码调用。

似乎到这里断了,不过为了一探究竟,我们继续找到了C代码。

在Java里是unsafe类的compareAndSwapInt(),在底层代码里对应的是unsafe.cpp文件中:

 

 

 我们观察到第1217行可知:最后调用的是Atomic::cmpxchg()方法,熟悉C/C++的话,就知道,这是stomic.cpp文件中的cmpxchg方法。

再点进去追击:

 

 

 可看到第56行是cmpxchg()方法,一路追踪,我们可发现,到最后是到了atomic_linux_x86.inline.cpp文件中。

找到Atomic.cpp文件中的cmpxchg()方法。

 

 

 在这里我们看:

在第95行有个LOCK_IF_MP() ,这其实是个宏定义,意思是是否是多核(Multi Processor):

 

 

 再继续追击,最后,我们知道最终的实现是依靠底层的 lock cmpxchg  指令(CPU级别)。 

虽然我们从代码可知,在多核(CPU)时才加lock,单核(CPU)不加。如:6 核12线程,我们在这里视为12核。故,单核情况下,指的就是自己线程不会打断自己。

cmpxchg 并不是原子性的,保证原子性还是依靠前面的 Lock。所以,我们才说底层代码直接支持CAS,是一把悲观锁,可以是缓存锁,也可以是总线锁。

 

 

 

 

Over......

标签:CAS,unsafe,AtomicInteger,剖析,cmpxchg,cpp,底层
来源: https://www.cnblogs.com/gjmhome/p/15145375.html