CAS-CompareAndSet源码分析

CAS是什么?

第一反应应该有两种:
1、Cas单点登录,当然本次不讨论这一方面的问题;
2、compareAndSet方法,先学习其API,再精通原理,才是我们学习代码的正确方法,不要被我们小时候填鸭式的教学影响,和学习数学、英语等知识学科不同,因此直接来一段代码:

CAS API用法:

	//原子操作
	AtomicInteger atomicInteger = new AtomicInteger(5);
	//期望值为5,若和5相同,则改为2019
	System.out.println(atomicInteger.compareAndSet(5, 2019)+"\t current data:"+atomicInteger.get());
	System.out.println(atomicInteger.compareAndSet(5, 1024)+"\t current data:"+atomicInteger.get());
	atomicInteger.getAndIncrement();

再结合以下的图形解答,了解相关API用法:
在这里插入图片描述
通过次演示,我们应该已经理解了,cas的基本用法:

CAS的全称为Compare-And-Swap,它是一条CPU并发原语。
它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的。

一句话总结:多线程下,与物理内存上数据相同则修改,反之不修改

CAS原理

1、查看Cas源码:

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

2、进去compareAndSwapInt内部,发现方法是被native修饰的;

	...//其他代码
  	public native void throwException(Throwable var1);

    public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

    public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
    ...//其他代码
3.1、Unsafe类

是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native) 方法来访问,Unsafe相当于一个后门,基于该
类可以直接操作特定内存的数据。Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作的执行依赖于Unsafe类的方法。
注意:Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务

3.2、变量valueOffset

表示该变量值在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的。

	/**
	* Atomically increments by one the current value .
	* @return the previous value
	* */
	public final int getAndIncrement() {
		return unsafe.getAndAddInt(this, valueOffse, 1);
	}
3.3、变量value用volatile修饰,保证了多线程之间的内存可见性。

详情比较原理:

	...//其他代码
    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;
    }
    ...//其他代码

AtomicInteger为何用Cas,而不用synchronized?

Synchronized是只允许一个线程运行(synchronized原理),虽然一致性保证了,但是降低并发性,而cas底层是unsafe,并且不加锁,保证一致性,允许多个线程同时操作,并发量得到保障,但是循环比较多。
参考链接:

https://www.bilibili.com/video/BV1zb411M7NQ?p=13&spm_id_from=pageDriver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值