Java面试题(五) 揭开CAS大美女的神秘面纱

一. CAS定义

1. CAS:比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。

2. 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 

3. 这是作为单个原子操作完成的。 

4. 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 

5. 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科)

二. 简单案例演示

 public static void main(String[] args) {

        //主物理内存设置为 3
        AtomicInteger atomicInteger = new AtomicInteger(3); //默认是 0

        //main线程打算在工作内存修改值为 2020
        System.out.println(atomicInteger.compareAndSet(3, 2020)+"\t current data: " + atomicInteger.get());
        
        //main线程打算在工作内存修改值为 1024      
        System.out.println(atomicInteger.compareAndSet(3, 1024)+"\t current data: " + atomicInteger.get());
    }

运行结果:
在这里插入图片描述

结果解析
为什么会出现上面的结果呢?

1. 因为compareAndSet(?,?)方法第一个参数代表的是期望值,
这个值负责和主内存也就是我们定义的3比较,如果相同,就返回true,并且把主存的值给交换掉。

所以会在控制台打印第一句话: true	 current data: 2020

3. 因为现在主内存的值已经被更改为2020,
所以3与之比对失败,返回false,输出主内存的值

这就是控制台打印的第二句话:false	 current data: 2020

三. CAS的底层原理

我们可以看一下其底层代码

以atomicInteger.getAndIncrement();方法为例进入底层

进入一层是AtomicInteger类

 	/**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

在下一层是Unsafe类

public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

解析代码

var1 AtomicInteger对象本身
var2 该对象的引用地址
var4 需要变动的数据
var5 通过var1 var2找出的主内存中真实的值用该对象前的值与var5比较;
如果相同,更新var5+var4并且返回true,退出循环。
如果不同,继续循环取值然后再比较,直到更新完成。
var5 = this.getIntVolatile(var1, var2); 相当于从主内存中取出值复制副本到工作内存。
this.compareAndSwapInt(var1, var2, var5, var5 + var4) 相当于是主内存的值与工作内存的值比较,相同,则改变值。

CAS的缺点

1.** 循环时间长,开销大**
	例如getAndAddInt方法执行,有个do while循环,
	如果CAS失败,一直会进行尝试,如果CAS长时间不成功,
	可能会给CPU带来很大的开销

2.只能保证一个共享变量的原子操作
	对多个共享变量操作时,循环CAS就无法保证操作的原子性,
	这个时候,就可以用锁来保证原子性

3.可能会引发ABA问题
总结:主要理解CAS与Synchronized的区别和CAS底层源码的实现。

下一篇:解决CAS大美女引来的ABA渣男

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值