CAS ABA问题
java.util.concurrent包的最底层基础CAS技术,原理很简单。
CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
引发ABA问题:如果变量V初次读取的时候是A,并且在准备赋值的时候检查到它仍然是A,那能说明它的值没有被其他线程修改过了吗?如果在这段期间它的值曾经被改成了B,然后又改回A,那CAS操作就会误认为它从来没有被修改过。
举例:
线程1准备用CAS将变量的值由A替换为B,在此之前,线程2将变量的值由A替换为C,又由C替换为A,然后线程1执行CAS时发现变量的值仍然为A,所以CAS成功。但实际上这时的现场已经和最初不同了,尽管CAS成功,但可能存在潜藏的问题,例如下面的例子:

现有一个用单向链表实现的堆栈,栈顶为A,这时线程T1已经知道A.next为B,然后希望用CAS将栈顶替换为B:
head.compareAndSet(A,B);
在T1执行上面这条指令之前,线程T2介入,将A、B出栈,再pushD、C、A,此时堆栈结构如下图,而对象B此时处于游离状态:

此时轮到线程T1执行CAS操作,检测发现栈顶仍为A,所以CAS成功,栈顶变为B,但实际上B.next为null,所以此时的情况变为:

其中堆栈中只有B一个元素,C和D组成的链表不再存在于堆栈中,平白无故就把C、D丢掉了。
解决办法:针对这种情况,java并发包中提供了一个带有标记的原子引用类"AtomicStampedReference"(版本戳),它可以通过控制变量值的版本来保证CAS的正确性。
CAS ABA问题的更多相关文章
- CAS / ABA
CAS / ABA 标签(空格分隔): 操作系统 1. CAS 解决 Volatile 不保证原子性的问题 /** * Atomically increments by one the current ...
- JDK对CAS ABA问题解决-AtomicMarkableReference和AtomicStampedReference
我们知道AtomicInteger和AtomicLong的原子操作,但是在这两个类在CAS操作的时候会遇到ABA问题,可能大家会疑问什么是ABA问题呢,请待我细细道来: ABA问题:简单讲就是多线程环 ...
- Java CAS ABA问题发生的场景分析
提到了CAS操作存在问题,就是在CAS之前A变成B又变回A,CAS还是能够设置成功的,什么场景下会出现这个问题呢?查了一些资料,发现在下面的两种情况下会出现ABA问题. 1.A最开始的内存地址是X,然 ...
- Java并发编程原理与实战四十三:CAS ---- ABA问题
CAS(Compare And Swap)导致的ABA问题 问题描述 多线程情况下,每个线程使用CAS操作欲将数据A修改成B,当然我们只希望只有一个线程能够正确的修改数据,并且只修改一次.当并发的时候 ...
- CAS -- ABA问题的解决方案
我们现在来说什么是ABA问题.假设内存中有一个值为A的变量,存储在地址V中. 此时有三个线程想使用CAS的方式更新这个变量的值,每个线程的执行时间有略微偏差.线程1和线程2已经获取当前值,线程3还未获 ...
- DLC双端锁,CAS,ABA问题
一.什么是DLC双端锁?有什么用处? 为了解决在多线程模式下,高并发的环境中,唯一确保单例模式只能生成一个实例 多线程环境中,单例模式会因为指令重排和线程竞争的原因会出现多个对象 public cla ...
- 一篇文章快速搞懂 Atomic(原子整数/CAS/ABA/原子引用/原子数组/LongAdder)
前言 相信大部分开发人员,或多或少都看过或写过并发编程的代码.并发关键字除了Synchronized,还有另一大分支Atomic.如果大家没听过没用过先看基础篇,如果听过用过,请滑至底部看进阶篇,深入 ...
- 沉淀再出发:java中的CAS和ABA问题整理
沉淀再出发:java中的CAS和ABA问题整理 一.前言 在多并发程序设计之中,我们不得不面对并发.互斥.竞争.死锁.资源抢占等等问题,归根到底就是读写的问题,有了读写才有了增删改查,才有了所有的一切 ...
- 第47天打卡学习(单例模式 深入了解CAS 原子引用 各种锁的理解)
18彻底玩转 单例模式 饿汉式 DCL懒汉模式 探究! 饿汉式 package com.kuang.single; //饿汉式单例 //单例模式重要思想是构造器私有 public class Hun ...
随机推荐
- IDEA+maven搭建scala开发环境(spark)(半转载)
以下内容部分来自于https://zhuanlan.zhihu.com/p/23141509,我尝试了一遍,然后添加了一些图片.. 其实我觉得在IDEA中使用scala插件然后创建project的时候 ...
- Jersey用户指南学习笔记1
Jersey用户指南是Jersey的官方文档, 英文原版在这:https://jersey.github.io/documentation/latest/index.html 中文翻译版在这:http ...
- Multiple dex files define Lokhttp3/internal/wsWebSocketProtocol
Multiple dex files define Lokhttp3/internal/wsWebSocketProtocol 老套路,先晒图 图一:如题,在编译打包时遇到了如上错误,很明显这是一个依 ...
- (三十九)c#Winform自定义控件-面包屑导航
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- Redis总结(九)Linux环境如何安装redis
以前总结Redis 的一些基本的安装和使用,由于是测试方便,直接用的window 版的reids,并没有讲redis在linux下的安装.今天就补一下Linux环境如何安装redis. 大家可以这这里 ...
- springboot+支付宝条码支付开发详解
背景:项目原有乐刷聚合支付,无法参加支付宝.微信等支付机构的官方活动 需求:增加原生支付(支付宝条码支付) 方法: 一.官方文档:https://docs.open.alipay.com/194/10 ...
- Docker进阶-资源管理Swarm+Portainer
Docker Swarm资源管理 Docker Swarm是Docker官方三剑客项目之一,提供Docker容器集群服务,是Docker官方对容器云生态进行支持的核心方案. 使用它,用户可以将多个Do ...
- 我是如何学习写一个操作系统(二):操作系统的启动之Bootloader
前言 今天本来的任务看书和把之前写的FragileOS整理一下,但是到现在还在摸鱼,书也只看一点.后来整理了一下写这个系列的思路,原本的目的是对操作系统原理性的学习和对之前写的一个玩具型操作系统的回顾 ...
- 纯 CSS 实现绘制各种三角形(各种角度)
一.前言 三角形实现原理:宽度width为0:height为0:(1)有一条横竖边(上下左右)的设置为border-方向:长度 solid red,这个画的就是底部的直线.其他边使用border-方向 ...
- Scrapy框架解读
1. Scrapy组件a. 主体部分i. 引擎(Scrapy):处理整个系统的数据流处理,触发事务(框架核心)ii. 调度器(Scheduler):1) 用来接受引擎发过来的请求, 压入队列中, 并在 ...