栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

CAS基础及底层原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CAS基础及底层原理

目录

 

一.CAS基本概念及运用

二.CAS底层原理1

三.CAS底层原理2

四.CAS的缺点


一.CAS基本概念及运用

CAS表层意思就是compareAndSet即比较并交换

 CAS的全称为Compare-And-Swap ,它是一条CPU并发原语,比较工作内存值(预期值)和主物理内存的共享值是否相同,相同则执行规定操作,否则继续比较直到主内存和工作内存的值一致为止。这个过程是原子的
(AtomicInteger类主要利用CAS(compare and swap)+volatile和native方法来保证原子操作,从而避免synchronized的高开销,执行效率大为提升)


代码如下:

import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(6);
        //compareAndSet(int expect,int update) 如果期望值expect与工作内存中的值相同则修改 否则修改失败
        //与期望值相同 atomicInteger修改为2021
        System.out.println(atomicInteger.compareAndSet(6,2021)+"t current data is "+atomicInteger.get());//true
        //上述操作atomicInteger修改为2021与期望值6不同 所以修改失败
        System.out.println(atomicInteger.compareAndSet(6,2022)+"t current data is "+atomicInteger.get());//false
    }
}

 结果如下:

 分析:首先我们new的atomicInteger对象传的值是6,compareAndSet(int expect,int update)是底层的参数,第一组传的值是compareAndSet(6,2021),这里的expect=6与atomicInteger=6的值对比后发现一样,则返回true,把atomicInteger的值更新为2021,同理第二组传的值是compareAndSet(6,2022),这里的expect=6与atomicInteger=2021的值对比后发现不一样,则返回false,atomicInteger的值不更新且仍然为2021

二.CAS底层原理1

为什么说CAS能保证原子性?线程安全?

①CAS并发原语提现在Java语言中就是sun.misc包下的UnSaffe类中的各个方法.调用UnSafe类中的CAS方法,JVM会帮我实现 CAS汇编指令. 这是一种完全依赖于硬件 功能,通过它实现了原子操作,再次强调,由于CAS是一种系统原语,原语属于操作系统用于范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许中断,也即是说CAS是一条原子指令,不会造成所谓的数据不一致的问题

②getAndIncrement()方法

首先先来看getAndIncrement()的源码,它里面使用了getAndAddInt()的方法,传了this,valueoffset,i三个参数

 继续点开getAndAddInt()方法

 这个方法就是CAS思想,var 1对应this当前对象,var 2对应valueOffset地址偏移量,var 4对应i:1,当执行var5 = this.getIntVolatile(var1, var2);时,把var 1当前对象以及var 2地址偏移量赋值给var 5,执行while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));时,var 1和var 5对比,如果相同,则值没有被动过,然后var 5+var 4,并返回true,再取反得到false退出循环。反之,值被修改过,则再次进入循环。

③unSafe类(rt.jar下的原生类)

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

 变量ValueOffset是该变量在内存中的偏移地址,UnSafe就是根据内存偏移地址获取数据的!

变量value和volatile修饰,保证了多线程之间的可见性!

 三.CAS底层原理2

小结:

(1)CAS:比较当前工作内存中的值和主内存中的值,如果相同则执行规定操作,否则继续比较直到主内存和工作内存中的值一致为止。

(2)CAS应用:CAS有3个操作数,内存值V,旧的预期值A,要修改的更新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

四.CAS的缺点

①循环时间长开销大

我们可以看到getAndAddInt方法执行时,有个do while,如果CAS失败,会一直进行尝试,如果CAS长时间不成功,可能给CPU带来很大的开销

tips:Unsafe类+CAS(自旋锁)

 ②只能保证一个共享变量的原子性

当对一个共享变量执行操作时,我们可以使用循环CAS方式来保证原子性

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

③引出ABA问题

小知识点:CAS用了一种折中的方法,没有加锁,允许多线程并发修改,并发性加强,采用互相比较的方式。

synchronized是加锁,同一时间段只有一个线程过来,完成一个线程才能开启另外一个线程,并发性下降。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/271230.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号