CAS及其ABA问题
CAS、volatile是JUC包实现同步的基础。Synchronized下的偏向锁、轻量级锁的获取、释放,lock机制下锁的获取、释放,获取失败后线程的入队等操作都是CAS操作锁标志位、state、队列完成的。
CAS过程
CAS的全称是Compare And Swap 即比较交换 ,是系统原语,由一系列系统的指令组成,不可被分割,简单的说就是CAS操作时一个原子性的操作。在sun.misc.unsafe类中,所有方法都是native的,都直接调用操作系统底层资源执行相应任务,比如直接操作内存,Java中CAS操作的执行依赖于Unsafe类的方法。其算法核心思想如下
其包含3个参数
V表示要更新的变量(即内存中的某变量的当前值)
E表示预期值
N表示新值
CAS操作需要我们提供一个期望值E,当 E == V 时,说明还没线程修改该值,当前线程可以进行修改为N,但如果期望值与当前线程不符,则说明该值已被其他线程修改,此时不执行更新操作,但可以选择重新读取该变量再尝试再次修改该变量 (也叫自旋) ,也可以放弃操作。
CAS的ABA问题
虽然CAS可以用很小的开销完成某些需要同步的操作,但也存在一些问题,比如ABA问题,并发量大的情况下自旋消耗过大的问题。关于ABA问题,举例说明:
我买东西付款100元后,由于一些原因,发起了两个付款线程 1、2。线程1 预期我的账户内存中的值为A元钱,要把它-100修改为B元。
这时线程1阻塞了,线程2顺利执行把A改为B。(正常情况下,线程1应该是CAS失败的,因为内存值B以经不等于它的预期值A了)
线程1还没来得及继续执行,你给我转账100元,并且这个转账 线程3 顺利执行完毕,我的账户+100,又变成A元。
在转账线程3完成后,线程1终于又开始执行了,它发现内存值还是A,于是它会执行扣款操作。我平白无故损失100元。
简单的说,ABA问题是: 两个进行同样操作的线程,本来是应该只能有一个操作成功,但是由与第三者介入二者之间修改数据,迷惑了二者中后执行的线程,使两个线程同样的操作都执行成功了。 比如扣了两次款!
解决办法是给我的余额值加个版本号,经过一次修改就更新一次版本。对于有些情况, 预期中的值、版本号 == 内存中值、版本号, 即二者都想等,才执行更新操作。
CAS及其ABA问题的更多相关文章
- 沉淀再出发:java中的CAS和ABA问题整理
沉淀再出发:java中的CAS和ABA问题整理 一.前言 在多并发程序设计之中,我们不得不面对并发.互斥.竞争.死锁.资源抢占等等问题,归根到底就是读写的问题,有了读写才有了增删改查,才有了所有的一切 ...
- java并发编程(十三)----(JUC原子类)引用类型介绍(CAS和ABA的介绍)
这一节我们将探讨引用类型原子类:AtomicReference, AtomicStampedRerence, AtomicMarkableReference.AtomicReference的使用非常简 ...
- Java高性能编程之CAS与ABA及解决方法
Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...
- CAS的ABA问题详解
CAS的ABA问题详解 ABA问题 在多线程场景下CAS会出现ABA问题,关于ABA问题这里简单科普下,例如有2个线程同时对同一个值(初始值为A)进行CAS操作,这三个线程如下 1.线程1,期望值为A ...
- CAS 和 ABA 问题
CAS简介 CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制. CAS 它是一条CPU并发原语.操作包含三个操作数 -- 内存位置.预期数值和新值.CAS ...
- Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)
摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...
- Java CAS 和ABA问题
独占锁:是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁:每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功 ...
- 无锁编程(四) - CAS与ABA问题
CAS 一般采用原子级的read-modify-write原语来实现Lock-Free算法,其中LL和SC是Lock-Free理论研究领域的理想原语,但实现这些原语需要CPU指令的支持,非常遗憾的是目 ...
- 谈论高并发(十二)分析java.util.concurrent.atomic.AtomicStampedReference看看如何解决源代码CAS的ABA问题
于谈论高并发(十一)几个自旋锁的实现(五岁以下儿童)中使用了java.util.concurrent.atomic.AtomicStampedReference原子变量指向工作队列的队尾,为何使用At ...
随机推荐
- Linux设备驱动程序学习----2.内核模块与应用程序的对比
内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...
- java相关的一些资源
http://www.cnblogs.com/best/p/5876559.html#_label1
- 最基础的 ant build 脚本
最基础的 ant build 脚本,根据项目,自行进行修改 <?xml version="1.0" encoding="UTF-8" ?> < ...
- Oracle RAC 集群启动与停止
Oracle RAC 启动时,需要使用 root 用户执行,为了方便,写了启动和停止的脚本, 将该脚本放到 /root/bin ,因为bin 目录本身就在环境变量里,所以使用时直接root用户运行脚本 ...
- java虚拟机学习笔记(六)---垃圾收集算法
主要讨论集中垃圾收集算法的思想及发展过程. 1.标记-清除法 最基础的收集算法是标记-清除法,算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,其标记过程 ...
- APPCAN 版本控制SVN
1.检出代码 checkout 常规的操作 appcan 中,在官网新建一个项目后,就会有一项目的svn 地址,而且已经是主干分支了,这个是项目的位移目录,不能再trunk目录同级创建分子 ...
- Android Bluetooth Low Energy (BLE)简单方便的蓝牙开源库——EasyBLE
源码传送门 最新版本 功能 支持多设备同时连接 支持广播包解析 支持连接同时配对 支持搜索系统已连接设备 支持搜索器设置 支持自定义搜索过滤条件 支持自动重连.最大重连次数限制.直接重连或搜索到设备再 ...
- Oracle中查看最近被修改过的表的方法
1.select uat.table_name from user_all_tables uat 该SQL可以获得所有用户表的名称 2.select object_name, created,last ...
- xtuils
xutils的使用必须导入一个依赖 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceS ...
- postman 测试http,接口
1.form-data: 就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开.既可以上传键值对,也可以上传文件.当上传的字段是文件时 ...