cas是什么

  CAS 全称 compare and swap 或者compare and exchange  比较并且交换。用于在没有锁的情况下,多个线程对同一个值的更新。

cas原理

  例如,我们对一个int i进行递增操作。原来,为了线程安全,需要在递增代码上加一把锁 sync 。CAS的实现方式为:不去加锁,读取当前的值,将原值存入E中,然后计算,得到计算结果1,这个时候的新值存入V中。然后调用一个比较并交换的方法(底层汇编指令) 这个方法的作用是:如果E和现在的i值相等,说明没有地方对原值进行过操作。那么就将i的值替换为V的值。
  如果有别的线程对i进行操作了(例如:i被修改为了2),那么将i的新值读取,然后再进行一次计算操作(将i=2 作为最初值,进行计算,得到结果3 )。然后再次调用比较并交换的方法,去进行值的更新操作。一直循环,直到更新成功(有的锁在更新到一定次数后,会进行锁升级,但是这个跟CAS没关系)

  CAS底层原理

  cas追代码的时候,可以追到native部分,但是,这里面提供的都是一些接口,但是没有具体的底层实现。具体的实现,需要看虚拟机的实现。

  jvm的底层实现分为不同的公司的不同实现:Oracle的为hotSpot实现,这个是最常见的。我们可以看到代码的开源版本是openjdk。比如阿里的taobaoVM 。Ibm 的J9等。

  在openjdk 中,unsafe类在实现CompareAndSwapInt 方法时,是调用的Atomic类的cmpxchg方法,然后一通方法调用,最终调用到汇编语言的 lock_if_mp(lock  if multi processors 如果是多个cpu 那么会锁定) cmpxchg 这两个 指令 ,最终执行 lock cmpxchg 指令
这里的lock是一一个锁定北桥芯片的锁,用于解决当前cpu在进行比较和修改的时候的其他cpu对该值进行操作的问题。保证线程安全。

aba问题

  在线程A进来时,读取到的值为1。在A进行计算的时候线程B取到了i的值,然后更新为了2。然后线程C又取到i=2的值,进行C的计算后,然后得到结果为1 又将i的值修改为了1 这个时候,线程A进行判断的时候,会认为在其计算过程中没有其他线程对i进行过操作。ABA有的会产生影响,有的不会,如果没有影响,不需要考虑该问题。

aba问题解决

  解决方法:加上版本号,每个线程读取完,赋值的时候,修改版本号,比较的时候,对比i值+版本号。

CAS(乐观锁)与ABA问题的更多相关文章

  1. CAS(乐观锁)以及ABA问题

    https://blog.csdn.net/wwd0501/article/details/88663621独占锁是一种悲观锁,synchronized就是一种独占锁:它假设最坏的情况,并且只有在确保 ...

  2. Java性能 -- CAS乐观锁

    synchronized / Lock / CAS synchronized和Lock实现的同步锁机制,都属于悲观锁,而CAS属于乐观锁 悲观锁在高并发的场景下,激烈的锁竞争会造成线程阻塞,而大量阻塞 ...

  3. [数据库锁机制] 深入理解乐观锁、悲观锁以及CAS乐观锁的实现机制原理分析

    前言: 在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念.数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务 ...

  4. 并发之ATOMIC原子操作--CAS乐观锁原理(二)

    1.乐观锁介绍 程序完成并发操作时,访问数据时每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功为止.就是当去做某个修改或其他操作的时候它认为不会有其他线程来做同样的操作(竞争) ...

  5. redis的高级事务CAS(乐观锁)

    Optimistic locking using check-and-set(乐观锁) 乐观锁介绍:watch指令在redis事物中提供了CAS的行为.为了检测被watch的keys在是否有多个cli ...

  6. Java:CAS(乐观锁)

    本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助. 什么是悲观锁.乐观锁?在java语言里,总有一些名 ...

  7. JAVA多线程学习四 - CAS(乐观锁)

    本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助. 什么是悲观锁.乐观锁?在java语言里,总有一些名 ...

  8. java 乐观锁CAS

    乐观锁是一种思想,本身代码里并没有lock或synchronized关键字进行修饰.而是采用一种version. 即先从数据库中查询一条记录得到version值,在更新这条记录时在where条件中对这 ...

  9. Java并发:乐观锁

    作者:汤圆 个人博客:javalover.cc 简介 悲观锁和乐观锁都属于比较抽象的概念: 我们可以用拟人的手法来想象一下: 悲观锁:像有些人,凡事都往坏的想,做最坏的打算:在java中就表现为,总是 ...

随机推荐

  1. .Net基础之2——C#基础

    1.注释符的作用   1).注销                  2).解释 2.C#中的3种解释符 1).单行注释(//要注释的内容) //这行代码的作用是将hello world输出到控制台上 ...

  2. vue 配置移动单位转换插件 postcss-px-to-viewport

    1.先安装插件 npm install postcss-px-to-viewport --save-dev 2.在文件根目录下添加 postcss.config.js 文件 module.export ...

  3. WordPress 获取文章内容页特色图像地址

    WordPress获取特色图像地址主要需要用到两个函数get_post_thumbnail_id和wp_get_attachment_image_src.下面是分别获取小.中.大.完整.指定图片规格的 ...

  4. docker的镜像加速

    docker加速配置 1,阿里云镜像加速 1.登录:https://dev.aliyun.com/search.html 2.登录阿里云 搜索   容器镜像服务  找到后如下图 ‘ 您可以通过修改da ...

  5. akka-typed(1) - actor生命周期管理

    akka-typed的actor从创建.启用.状态转换.停用.监视等生命周期管理方式和akka-classic还是有一定的不同之处.这篇我们就介绍一下akka-typed的actor生命周期管理. 每 ...

  6. 创建多线程的方式&Thread类的常用方法

    创建多线程的第一种方式:继承java.lang.Thread类 注意:1.一个线程只能执行一次start() 2.不能通过Thread实现类对象的 run()去启动一个线程 3.增加加一个线程,需要新 ...

  7. 【Python】自己写日志功能

    Python有自带的logging模块,用于日志记录,功能很强大,但不好用,使用挺麻烦的,而且发现了几个bug,调用了一个logger.warning()一次,结果日志文件中出现了n行记录,且逐渐变成 ...

  8. 使用Burpsuite对手机抓包的配置

    之前使用dSploit的时候就一直在想怎么对手机进行抓包分析,前两天使用了Burpsuite神器,发现通过简单的配置就可以抓手机app的数据包了,进而分析手机app的流量. 配置环境: 1.win7下 ...

  9. HTTP 冷知识 | HTTP 请求中,空格应该被编码为 %20 还是 + ?

    HTTP 请求中,空格应该被编码为什么?今天我们走进 RFC 文档和 W3C 文档,了解一下这个「史诗级」大坑. 1.%20 还是 + ? 开始讲解前先看个小测试,在浏览器里输入 blank test ...

  10. Java实现 LeetCode 453 最小移动次数使数组元素相等

    453. 最小移动次数使数组元素相等 给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数.每次移动可以使 n - 1 个元素增加 1. 示例: 输入: [1,2,3] 输出: 3 ...