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问题的更多相关文章

  1. CAS / ABA

    CAS / ABA 标签(空格分隔): 操作系统 1. CAS 解决 Volatile 不保证原子性的问题 /** * Atomically increments by one the current ...

  2. JDK对CAS ABA问题解决-AtomicMarkableReference和AtomicStampedReference

    我们知道AtomicInteger和AtomicLong的原子操作,但是在这两个类在CAS操作的时候会遇到ABA问题,可能大家会疑问什么是ABA问题呢,请待我细细道来: ABA问题:简单讲就是多线程环 ...

  3. Java CAS ABA问题发生的场景分析

    提到了CAS操作存在问题,就是在CAS之前A变成B又变回A,CAS还是能够设置成功的,什么场景下会出现这个问题呢?查了一些资料,发现在下面的两种情况下会出现ABA问题. 1.A最开始的内存地址是X,然 ...

  4. Java并发编程原理与实战四十三:CAS ---- ABA问题

    CAS(Compare And Swap)导致的ABA问题 问题描述 多线程情况下,每个线程使用CAS操作欲将数据A修改成B,当然我们只希望只有一个线程能够正确的修改数据,并且只修改一次.当并发的时候 ...

  5. CAS -- ABA问题的解决方案

    我们现在来说什么是ABA问题.假设内存中有一个值为A的变量,存储在地址V中. 此时有三个线程想使用CAS的方式更新这个变量的值,每个线程的执行时间有略微偏差.线程1和线程2已经获取当前值,线程3还未获 ...

  6. DLC双端锁,CAS,ABA问题

    一.什么是DLC双端锁?有什么用处? 为了解决在多线程模式下,高并发的环境中,唯一确保单例模式只能生成一个实例 多线程环境中,单例模式会因为指令重排和线程竞争的原因会出现多个对象 public cla ...

  7. 一篇文章快速搞懂 Atomic(原子整数/CAS/ABA/原子引用/原子数组/LongAdder)

    前言 相信大部分开发人员,或多或少都看过或写过并发编程的代码.并发关键字除了Synchronized,还有另一大分支Atomic.如果大家没听过没用过先看基础篇,如果听过用过,请滑至底部看进阶篇,深入 ...

  8. 沉淀再出发:java中的CAS和ABA问题整理

    沉淀再出发:java中的CAS和ABA问题整理 一.前言 在多并发程序设计之中,我们不得不面对并发.互斥.竞争.死锁.资源抢占等等问题,归根到底就是读写的问题,有了读写才有了增删改查,才有了所有的一切 ...

  9. 第47天打卡学习(单例模式 深入了解CAS 原子引用 各种锁的理解)

    18彻底玩转 单例模式 饿汉式 DCL懒汉模式 探究! 饿汉式  package com.kuang.single; //饿汉式单例 //单例模式重要思想是构造器私有 public class Hun ...

随机推荐

  1. Java连载16-++传参&关系运算符

    一.++再举例 int a = 10; System.out.print(a++);//这里会打印出10,因为他们内部这个print函数有参数相当于参数x=a++ System.out.println ...

  2. Statement和PreparedStatement

    Statement与PreparedStatement的关系和区别: 关系:PreparedStatement继承自Statement,都是接口. 区别:PreparedStatement可以使用占位 ...

  3. JavaWeb购物车

    一.类关系 最近又把JavaWeb方面的知识(Servlet.jsp等)过了一遍,发现以前还是接触的太窄太浅.加上才转到IntelliJ IDEA 上故而想用这个项目练练,就当熟悉熟悉IntelliJ ...

  4. Redis集群环境下的键值空间监听事件实现方案

    一直想记录工作中遇到的问题和解决的方法,奈何没有找到一方乐土,最近经常反思,是否需要记录平时的点滴,后台还是决定下定决心记录一些,以便以后用到的时候找不着,实现这样的一个功能主要也是业务所需要的. 需 ...

  5. junit单元测试框架

    一般我们写代码总想对方法测试一下结果,就存在这些问题: 1.如果方法需要测试,都需要在main方法上调用 2.目前的结果都需要我们人工对比 所以就需要用到 junit 进行测试: 1·下载 junit ...

  6. JSON格式提取相同属性的某个值

    [ {UID:"222",value:"111"}, {UID:"222",value:"103"}, {UID:&qu ...

  7. Codeforces 976E

    题意略. 思路: 容易知道那a次倍增放在同一个怪身上是最优的,其余的怪我们只需要取hp值和damage值中间最大的那个就好了(在b值的限制下). 然而我们并不知道把那a次倍增放在哪个怪身上最好,那么我 ...

  8. Javaweb之国际化

    Javaweb之国际化 一.前言 软件的本地化:一个软件在某个国家或地区使用时,采用该国家或地区的语言,数字,货币,日期等习惯. 软件的国际化:软件开发时,让它能支持多个国家和地区的本地化应用.使得应 ...

  9. cogs2823求组合数(lucas定理

    http://cogs.pro:8080/cogs/problem/problem.php?pid=vNQJJVUVj 再写个数学水题,其实lucas适用于m,n比较大而p比较小的情况. 题意:给出两 ...

  10. HYSBZ - 4016 最短路径树问题 点分治 + 最短路径最小字典序

    题目传送门 题解:首先对于给定的图,需要找到那些从1好点出发然后到x号点的最短路, 如果有多条最短路就要找到字典序最小的路,这样扣完这些边之后就会有一棵树.然后再就是很普通的点分治了. 对于扣边这个问 ...