多线程、高并发笔记(四):CAS

CAS

CAS(Compare And Swap)是由硬件实现的.

可以将read modify write 这类的操作转换为原子操作。 i++自增操作包括三个子操作: 从主内存读取i的变量值
加1 再把加一之后的值保存到主内存.

原理

在把数据更新到主内存时,再次读取主内存变量的值,如果现在变量的值与期望的值(操作起始时读 取的值)一样就更新.

在这里插入图片描述

前提

CAS实现原子操作的背后有一个假设:

共享变量的当前值与当前线程提供的期望值相同,就认为这个变量没有被其他线程修改过。 实际上这种假设不一定成立。

如:共享变量count=0 A线程对值修改为10 B线程修改为20 C线程修改为0; 当前线程看到count变量的值现在是0 ,现在是否认为count的值没有别其他线程更新呢?这种结果是否能够接受; 这就是CAS中的ABA 问题,即共享变量经历了A->B->A的更新; 是否能够接受ABA问题跟实现的算法有关;

如果想规避ABA问题,可以为共享变量引入一个修订号,每次修改共享变量时,响应的修订号就更新,每次对共享变量的修改都会导致修订号的增加,通过修订号来准确判断变量是否被其他线程修改过。 AtomicStampedReference类就是基于这种思想产生的。

原子变量类

基于CAS实现的,当对共享变量进行reda-modify-write更新操作时,通过原子变量类可以保障操作的原子性与可见性。对变量的
reda-modify-write的更新操作不是一个简单的赋值, 而是变量的新值依赖变量的旧值。

如:

自增i++

由于volatile只能保证可见性,无法保证原子性,原子变量内部就是借助一个volatile变量,并且保障了该变量的操作原子性,有时把原子变量类看作是增强的volatile变量。

分组原子变量类
基础数据型AtomicInteger, AtomicLong, AtomicBoolean
数组型AtomicIntegerArray, AtomicLongArray,AtomicReferenceArray
字段更新器AtomicIntegerFieldUpdater,AtomicLongFieldUpdater, AtomicReferenceFieldUpdater
引用型AtomicReference, AtomicStampedReference, AtomicMarkableReference
例:
  • AtomicIntegerArray :原子更新数组

  • AtomicIntegerFieldUpdater:可以对原子整数字段进行更新

    要求: a、字段必须使用volatitle修饰,使线程之间可见 b、只能使实例变量,不能是静态变量,也不能使用final修饰

  • AtomicReference :可以原子读写一个对象 ,但是会出现ABA问题

  • AtomicStampedReference:可以解决ABA问题(加时间戳)

  • AtomicMarkableReference:可以解决ABA问题(加一个标志)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值