什么是CAS

学习Java并发编程,CAS(Compare And Set)机制都是一个不得不掌握的知识点。除了通过synchronized进行并发控制外,还可以通过CAS的方式控制,大家熟悉的ReentrantLock内部实现大量采用CAS进行控制。

CAS即Compare and Swap,即比较并交换。

CAS有三个操作数:内存值V、预期值A、要修改的值B,当且仅当预期值A和内存值V相同时,才将内存值修改为B,否则什么都不做。最后返回现在的V值。

CAS在任何一种情况下,都会返回V的真实值。(这个变量称为compare-and-set,无论操作是否成功都会返回。)CAS的意思是:“我认为V的值应该是A,如果是,那么将其赋值为B,若不是,则不修改,并告诉我应该为多少”。CAS是一项乐观技术,它抱着成功的希望进行更新,并且如果另一个线程在上次检查后更新了该变量,它能够发现错误。

CAS是由CPU指令来保证的,大多数的处理器都支持都实现了CAS指令。

CAS的优点

保证原子性的方式只有加锁,无论是内置锁(synchronized),还是显示锁(ReentrantLock),加锁意味着线程阻塞,如果竞争激烈,很可能导致频繁的线程上下文切换,从而大大降低了性能。

CAS机制是一种乐观锁,可以避免这些问题,使得执行效率很大的提高。

CAS典型应用场景

1、乐观锁思想

CAS解决并发的思路可以在很多场景中借鉴,在数据库使用中,可以采用这种方式来避免加锁操作,比如大家学习Hibernate时候的乐观锁。

2、Java Concurren

Java Concurrent包下大量使用CAS实现并发控制,比如Atomic*,ReentrantLock等。

比如AtomicInteger中,就使用CAS。

Java无法直接访问底层操作系统,而是通过本地(native)方法来访问。JVM开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作。

例如AtomicInteger的getAndSet方法:

public final int getAndSet(int newValue) {
     return unsafe.getAndSetInt(this, valueOffset, newValue);
 }

unsafe类的getAndSetInt

public final int getAndSetInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);//根据地址和偏移量获取数值
} while(!this.compareAndSwapInt(var1, var2, var5, var4));//重复尝试CAS操作
return var5;
}

通过调用unsafe的getlntVolatile(var1,var2),这是个native方法,其实就是获取var1中,var2偏移量处的值。var1就是Atomiclnteger对象本身,var2就是我们前面提到的偏移地址,这样我们就从内存里获取到现在偏移地址处的值了。

再通过compareAndSwapInt操作输入原值var5和目标值var4,如果操作成功返回,操作失败重新读取内存数据再次进行compareAndSwapInt直到成功。

CAS的缺点

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

1)ABA问题

CAS操作需要检查当前内存的变量值是否和刚刚读取的值相同,假设一个变量是A,变成了B,之后又变成了A,所以在进行CAS操作的时候检查到它的值没有发生变化。ABA的解决方案就是加上版本号1A->2B->3A,类似这种。java先行者们也给我们提供了AtomicStampedReference来解决ABA的问题,其中的预期标志也类似于版本号的功能。

2)循环时间长开销大

多线程竞争激烈的情况下进行CAS操作,会导致某些线程长时间空循环,也就是说它什么都没做,只是不停地在浪费处理器的处理时间而已。

3)只能保证一个共享变量的原子操作

一个共享变量的操作可以用CAS保证其原子性,多个共享变量的操作,循环CAS是无法保证其原子性的。有个取巧的办法,java先行者设计的AtomicReference类,我们可以通过将多个变量放到一个对象里面,然后由AtomicReference进行原子性地更新。

欢迎大家讨论并发的相关问题,也可以加我的头条号: IT技术研习社 。

聊聊CAS - 面试官最喜欢问的并发编程专题的更多相关文章

  1. 基础面试,为什么面试官总喜欢问String?

    关于 Java String,这是面试的基础,但是还有很多童鞋不能说清楚,所以本文将简单而又透彻的说明一下那个让你迷惑的 String 在 Java 中,我们有两种方式创建一个字符串 String x ...

  2. 一线大厂面试官最喜欢问的15道Java多线程面试题

    前言 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得更多职位,那么你应该准备很多关于多线程的问题. 他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者 ...

  3. 2019年面试官最喜欢问的28道ZooKeeper面试题

    前言 ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务.它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护.域名服务.分布式同步.组服务等. ZooKeeper 的 ...

  4. 阿里面试官最喜欢问的21个HashMap面试题

    1.HashMap 的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点.当链表长度超过 8 时,链表转换为红黑树. transient Node<K,V>\[\ ...

  5. 深度分析:面试腾讯,阿里面试官都喜欢问的String源码,看完你学会了吗?

    前言 最近花了两天时间,整理了一下String的源码.这个整理并不全面但是也涵盖了大部分Spring源码中的方法.后续如果有时间还会将剩余的未整理的方法更新到这篇文章中.方便以后的复习和面试使用.如果 ...

  6. 2021超详细的HashMap原理分析,面试官就喜欢问这个!

    一.散列表结构 散列表结构就是数组+链表的结构 二.什么是哈希? Hash也称散列.哈希,对应的英文单词Hash,基本原理就是把任意长度的输入,通过Hash算法变成固定长度的输出 这个映射的规则就是对 ...

  7. 走向DBA[MSSQL篇] 面试官最喜欢的问题 ----索引+C#面试题客串

    原文:走向DBA[MSSQL篇] 面试官最喜欢的问题 ----索引+C#面试题客串 对大量数据进行查询时,可以应用到索引技术.索引是一种特殊类型的数据库对象,它保存着数据表中一列或者多列的排序结果,有 ...

  8. Java面试官最常问的volatile关键字

    在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯 ...

  9. 大厂面试官最常问的@Configuration+@Bean(JDKConfig编程方式)

    大厂面试官最常问的@Configuration+@Bean(JDKConfig编程方式)   现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法.一 ...

随机推荐

  1. 让Spring不再难懂-aop篇

    什么是aop AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP允许 ...

  2. 接口测试 requests的身份认证方式

    requests提供多种身份认证方式,包括基本身份认证.netrc 认证.摘要式身份认证.OAuth 1 认证.OAuth 2 与 OpenID 连接认证.自定义认证.这些认证方式的应用场景是什么呢? ...

  3. 阿里云系统安装部署Freeswitch

    1.安装vim apt-get install vim 2.修改镜像源 将/etc/apt/source.list的原有源注释掉,添加下面的源: deb http://mirrors.163.com/ ...

  4. mysql 优化2 慢查询

    默认情况下mysql不记录慢查询日志,需要在启动的时候指定 bin\mysqld.exe - -slow-query-log 通过慢查询日志定位执行效率较低的SQL语句.慢查询日志记录了所有执行时间超 ...

  5. 统计学方法(t-检验)

    数据出来要做几件事:首先判断数据是否符合正态分布,如果符合的话,就要进行t-检验,那么进行t-检验的作用在哪呢? t-检验主要用于样本含量较小(例如n<30),总体标准差σ未知的正态分布 htt ...

  6. DIP|PCN|CoevDB|PID|Y2H|RosettaDock Serve|元基因组学|微生物多样性

    生命组学: 比较真核生物有关呼吸链的gene是比较核外编码基因,因为与呼吸有关的功能在线粒体上,线粒体位于核外.想要查看两种基因是否具有相互作用,可以对不同物种的编码ATP6 和ATP8的直系同源基因 ...

  7. ionic2踩坑之ionic build android报错

    自己项目一直跑的好好好好的,build还是run都没问题,今天忽然一个小伙伴build一直报错.\ 错误如下: Error occurred during initialization of VMCo ...

  8. <JZOJ1286>太空电梯

    一道简单可爱的dp #include<cstdio> #include<iostream> #include<cstring> #include<algori ...

  9. java.lang.ClassNotFoundException :xxxxxxx

    码的!java.lang.ClassNotFoundException: org.springframework.jdbc.core.RowMapper这个错误搞了半天 因为写的项目是手动建的WEB- ...

  10. Bar条形图

    import matplotlib.pyplot as plt import numpy as np n = 12 X = np.arange(n) Y1 = (1 - X / float(n)) * ...