博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CAS(Compare and swap)
阅读量:3931 次
发布时间:2019-05-23

本文共 1613 字,大约阅读时间需要 5 分钟。

原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分(不可中断性)。将整个操作视作一个整体,资源在该次操作中保持一致,这是原子性的核心特征。

CAS(Compare and swap)

Compare and swap 比较和交换。属于硬件同步原语, 处理器提供了基本内存操作的原子性保证。

CAS操作需要输入两个数值,一个是旧值A(期望操作前的值)和一个新值B,在操作期间先对旧值进行比较,若没有发生变化,才交换成新值,发生了变化则不变换。

JAVA中的sun.misc.Unsafe类,提供了compareAndSwapInt()compareAndSwapLong()等几个方法实现CAS。在这里插入图片描述

J.U.C包内的原子操作封装类

在进行CAS操作的时候要对需要更新的变量用volatile修饰。

  • AtomicBoolean:原子更新布尔类型
  • AtomicInteger:原子更新整型
  • AtomicLong:原子更新长整型
  • AtomicIntegerArray:原子更新整型数组里的元素
  • AtomicLongArrary:原子更新长整型数组里的元素
  • AtomicReferenceArray:原子更新引用类型数组里的元素
  • AtomicIntegerFieldUpdater:原子更新整型的字段的更新器
  • AtomicLongFieldUpadter:原子更新长整型字段的更新器
  • AtomicReferenceFieldUpdater:原子更新引用类型里的字段
  • AtomicReference:原子更新引用类型
  • AtomicStampedReference:原子更新带有版本号的引用类型
  • AtomicMarkableReference:原子更新带有标记为的引用类型

AtomicInteger等类的底层就是利用CAS机制实现

1.8更新

计数器增强版,高并发下性能更好。

  • 更新器:DoubleAccumulator、LongAccumulator
  • 计数器:DoubleAdder、LongAdder

原理:分成多个操作单元,不同线程更新不同的单元只有需要汇总的时候才计算所有单元的操作。

场景:高并发频繁更新、不太频繁地读取。

JDK提出了高并发场景性能更好的累加计数器

CAS的三个问题

  1. 循环+CAS,自旋的实现让所有线程都处于高频运行,争抢CPU执行时间的状态。如果操作长时间不成功,会带来很大的CPU资源消耗。
  2. 仅针对单个变量的操作,不能用于多个变量来实现原子操作。
  3. A B A问题。
    在这里插入图片描述
  • thread 1、thread 2同时读取到 i = 0后,
  • thread 1、thread 2都要执行CAS(0,1)操作,
  • 假设thread 2操作在thread 1操作之后,则thread 1 执行成功,
  • thread 1 紧接着执行了CAS(1,0),将 i 的值改回0,
  • thread 2本应该失败的CAS(0 ,1)操作,此时却成功了。

会对链表的操作产生很大的影响,在两个线程操作的时候thread 1 和thread 2同时对一个链表进行操作之后,可能会导致原有的链表表头指向了其他节点,使得thread 2操作产生问题

在这里插入图片描述

原链表是A-B,thread 2先对链表中表头A进行操作,将C,D连上A节点,然后thread 1又对链表中表头A进行操作,又将A指向了B。操作失效。

还会对栈造成影响,造成栈失效,和链表问题类似,只要指向的那个节点还在,就会对后续进行操作,产生A B A问题。

在这里插入图片描述
栈顶一开始指向A-B,然后thread 2对栈进行操作,弹出A-B,压入B-C-D-A,然后thread 1又对线程进行操作,thread 1中A又会指向B,会让C-D失效。

解决方案: 用版本号进行修饰,匹配版本号来确定原数据是否被修改过。带有版本号的数字引用类型,可以实现版本号锁

转载地址:http://rmugn.baihongyu.com/

你可能感兴趣的文章
CSS 鼠标经过时改变table所在行的颜色
查看>>
某机字长为32位 存储容量为64MB 若按字节编址 它的寻址范围是多少
查看>>
C 实现在Sql Server中存储和读取Word文件
查看>>
Java笔记之JTextField JTextArea区别
查看>>
Android学习笔记之Spinner
查看>>
UVA 题目401 - Palindromes
查看>>
Android学习笔记之SeekBar
查看>>
题目26 孪生素数问题
查看>>
java web 连接mysql数据库
查看>>
java 多线程简介
查看>>
docker架构
查看>>
Docker Client创建与命令执行
查看>>
springMVC学习笔记
查看>>
PageRank算法与特征向量和特征值(eigenvector和eigenvalue)
查看>>
HITS算法--从原理到实现
查看>>
MapReduce原理
查看>>
zookeeper原理
查看>>
MapReduce入门
查看>>
WEB服务器、应用程序服务器、HTTP服务器区别
查看>>
归并排序(JAVA)
查看>>