关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、使用场景四、原理五、优劣5.1 缺点
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。
CAS其实就是Compare And Swap的一个缩写,顾名思义就是比较并交换,其实就是把当前值与你预期的值进行一个比较,是一种用于在多线程环境下实现同步功能的机制。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。
CAS是原子性的操作(读和写两者同时具有原子性),是让CPU比较内存中某个值是否和预期的值相同,如果相同则将这个值更新为新值,不相同则不做更新.
对比交换是一条CPU的原子指令,其实现方式是基于硬件平台的汇编指令。
CAS操作是原子性的,所以多线程并发使用CAS更新数据时,可以不使用锁。
使用volatile关键字可以保证可见性和有序性,但是却没有原子性,比如a++,引入cas就可以解决多线程的原子性问题。
CAS配合volatile来实现许多高并发类
Java中利用CAS的乐观锁、原子性的特性高效解决了多线程的安全性问题。
CAS这种方式适用于并发量不高的情况。
实现方式是通过借助C/C++调用CPU指令完成的,是一条CPU的原子指令,依赖于系统。
CAS的实现主要在JUC中的atomic包,存放在 java.util.concurrent.atomic 类路径下
如:自增长 AtomicInteger 等
Java中的CAS操作的执行依赖于Unsafe类,我们看下AtomicInteger的代码:
public class AtomicInteger extends Number implements java.io.Serializable { private static final Unsafe unsafe = Unsafe.getUnsafe(); private volatile int value; public AtomicInteger(int initialValue) { value = initialValue; } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapint(this, valueOffset, expect, update); } }
CAS配合volatile来实现多线程可见性有序性和原子性。
再看下Unsafe类
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
我们进入Unsafe类的native方法compareAndSwapInt,调用UnSafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令,这是一种完全依赖于硬件的功能,通过它实现了原子操作。
由于CAS是一种系统原语,原语属于操作系统用于范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS操作是一条CPU的原子指令,不会造成所谓的数据不一致的问题,所以说CAS是线程安全的。
假如一个线程操作数据,干了一半活,累了,想要去休息。(貌似今天的线程体质都不太好)。于是它记录下当前数据的状态(就是数据的值),回家睡觉了。 醒来后打算继续接着干活,但是又担心数据可能被修改了,于是就把睡觉前保存的数据状态拿出来和现在的数据状态比较一下,如果一样,说明自己在睡觉期间,数据没有被人动过(当然也有可能是先被改成了其它,然后又改回来了,这就是ABA问题了),那就接着继续干。如果不一样,说明数据已经被修改了,那之前做的那些操作其实都白瞎了,就干脆放弃,从头再重新开始处理一遍。
所以CAS这种方式适用于并发量不高的情况,也就是数据被意外修改的可能性较小的情况。如果并发量很高的话,你的数据一定会被修改,每次都要放弃,然后从头再来,这样反而花费的代价更大了,还不如直接加锁呢。
并发1(上):获取出数据的初始值是A,后续计划实施CAS乐观锁,期望数据仍是A的时候,修改才能成功
并发2:将数据修改成B
并发3:将数据修改回A
并发1(下):CAS乐观锁,检测发现初始值还是A,进行数据修改
并发1在修改数据时,虽然还是A,但已经不是初始条件的A了,
中间发生了A变B,B又变A的变化,此A已经非彼A,数据却成功修改,
可能导致错误,这就是CAS引发的所谓的ABA问题。
优化ABA问题:
“版本号”的比对,一个数据一个版本,版本变化,即使值相同,也不应该修改成功。
很好解决,再加一个版本号字段就行了,并规定只要修改数据,必须使版本号加1。
【Java基础】java可见性之 Happens-before
【Java基础】java-android面试Synchronized
【Java基础】 jvm 堆、栈、方法区 & java 内存模型
来源地址:https://blog.csdn.net/fumeidonga/article/details/131542090
--结束END--
本文标题: 【Java基础】CAS (Compare And Swap) 操作
本文链接: https://lsjlt.com/news/378379.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-04-01
2024-04-03
2024-04-03
2024-01-21
2024-01-21
2024-01-21
2024-01-21
2023-12-23
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0