Java并发 --- CAS解析(对比synchronized

2021-06-19  本文已影响0人  _code_x

什么是 CAS

那些地方采用了 CAS 机制

CAS底层实现

简单分析一下AtomicInteger的incrementAndGet的实现。

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}
private volatile int value;
public final int get() {
    return value;
}

这段代码是一个无限循环,也就是CAS的自旋。循环体当中做了三件事:

注意:

拓展一下:while(1) 和 for(;;)两种死循环:

while(1) :

  编译前              编译后 
while (1);         mov eax,1  
                    test eax,eax 
                    je foo+23h
                    jmp foo+18h
 for(;;):

    编译前              编译后 
for (;;);          jmp foo+23h 

总结:宏观功能相同的,但是底层编译后代码简洁很多。

那么compareAndSet方法如何保证原子性操作呢?

 public final boolean compareAndSet(int expect, int update) {
     return unsafe.compareAndSwapInt( this, valueOffset, expect, update);
}

compareAndSet方法的实现很简单,只有一行代码。这里涉及到两个重要的对象,一个是unsafe,一个是valueOffset

总结:关键在于unsafe提供硬件级别的原子操作。

CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。而unsafe的compareAndSwapInt方法参数包括了这三个基本元素:valueOffset参数代表了V,expect参数代表了A,update参数代表了B。正是unsafe的compareAndSwapInt方法保证了Compare和Swap操作之间的原子性操作。

CAS 的缺点及解决方式

CAS虽然很高效的解决原子操作,但是CAS仍然存在三大问题。ABA问题,循环时间长开销大和只能保证一个共享变量的原子操作

synchronized 和 CAS 的区别

所以,在并发量非常高的情况下,我们尽量的用同步锁,而在其他情况下,我们可以灵活的采用 CAS 机制。

巨人的肩膀

https://www.jianshu.com/p/335b0c273345
https://mp.weixin.qq.com/s/nRnQKhiSUrDKu3mz3vItWg
https://www.jianshu.com/p/12192b13990f

上一篇 下一篇

猜你喜欢

热点阅读