【JUC系列第三篇】-CAS算法详解

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。如需授权请联系微信:878799579 https://blog.csdn.net/qq_878799579/article/details/85636250 作者 : 毕来生微信: 8787995791、CAS是什么?CAS是英文单词(Compare-And-Swap)的缩写,中文意思是:比较并替换。
版权声明:本文为博主原创文章,未经博主允许不得转载。如需授权请联系微信:878799579 https://blog.csdn.net/qq_878799579/article/details/85636250

作者 : 毕来生
微信: 878799579


1、CAS是什么?

CAS是英文单词(Compare-And-Swap)的缩写,中文意思是:比较并替换。CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。

CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

Cas乐观锁算法演示
在这里插入图片描述

CAS优缺点

优点:

  1. 解决了部分情况下原子操作的问题
  2. 并发量不是很高时cas机制会提高效率。

缺点:

  1. 同一时间只能保证一个共享变量的原子操作(针对多个共享变量操作。循环CAS无法保证操作原子性,需要考虑通过加锁来保证原子性)

  2. 循环时间比较长,且开销时间比较大 : 如果尝试CAS失败,则会一直进行尝试。如果一直不成功。会对CPU带来较大负担

  3. 经典ABA问题

    如果内存地址V初次读取的值是A,并且在准备赋值的时候检查到它的值仍然为A,那我们就能说它的值没有被其他线程改变过了吗?

    如果在这段期间它的值曾经被改成了B,后来又被改回为A,那CAS操作就会误认为它从来没有被改变过。这个漏洞称为CAS操作的“ABA”问题。Java并发包为了解决这个问题,提供了一个带有标记的原子引用类“AtomicStampedReference”,它可以通过控制变量值的版本来保证CAS的正确性。因此,在使用CAS前要考虑清楚“ABA”问题是否会影响程序并发的正确性,如果需要解决ABA问题,改用传统的互斥同步可能会比原子类更高效。

如何解决经典ABA问题以及源码分析

通过JDK中自带的AtomicStampedReference类可以解决ABA问题。附上核心解决方法

	/**
     * Atomically sets the value of both the reference and stamp
     * to the given update values if the
     * current reference is {@code ==} to the expected reference
     * and the current stamp is equal to the expected stamp.
     *
     * @param expectedReference the expected value of the reference(期望值)
     * @param newReference the new value for the reference(写入新值)
     * @param expectedStamp the expected value of the stamp(期望的状态值)
     * @param newStamp the new value for the stamp(新的状态值)
     * @return {@code true} if successful
     */
    public boolean compareAndSet(V   expectedReference,
                                 V   newReference,
                                 int expectedStamp,
                                 int newStamp) {
        Pair<V> current = pair;
        return
            expectedReference == current.reference &&
            expectedStamp == current.stamp &&
            ((newReference == current.reference &&
              newStamp == current.stamp) ||
             casPair(current, Pair.of(newReference, newStamp)));
    }

    private boolean casPair(Pair<V> cmp, Pair<V> val) {
        return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
    }


因为casPair核心方法时通过native关键字修饰。故不能直接查看对应class源码。

public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5)

不能查看源码就能难住我们了?不存在的。

我们下载好openjdk源码后,将其导入到idea里该project的lib中,全局搜索。直接附上对应源码供大家参考

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
  UnsafeWrapper("Unsafe_CompareAndSwapObject");
  oop x = JNIHandles::resolve(x_h); // 新值
  oop e = JNIHandles::resolve(e_h); // 预期值
  oop p = JNIHandles::resolve(obj);
  HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);// 在内存中的具体位置
  oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);// 调用了另一个方法
  jboolean success  = (res == e);  // 如果返回的res等于e,则判定满足compare条件(说明res应该为内存中的当前值),但实际上会有ABA的问题
  if (success) // success为true时,说明此时已经交换成功(调用的是最底层的cmpxchg指令)
    update_barrier_set((void*)addr, x); // 每次Reference类型数据写操作时,都会产生一个Write Barrier暂时中断操作,配合垃圾收集器
  return success;
UNSAFE_END
目录
相关文章
|
5月前
|
缓存 算法 安全
从内存可见性看volatile、原子操作和CAS算法
从内存可见性看volatile、原子操作和CAS算法
25 0
|
10月前
|
设计模式 算法 安全
并发设计模式 之 CAS算法
并发设计模式 之 CAS算法
61 0
|
存储 算法 小程序
通过 JDK 原子并发类 AtomicInteger 彻底掌握 CAS 无锁算法
通过 JDK 原子并发类 AtomicInteger 彻底掌握 CAS 无锁算法
151 0
通过 JDK 原子并发类 AtomicInteger 彻底掌握 CAS 无锁算法
|
算法 Java
Java 模拟 CAS 算法
Java 模拟 CAS 算法
49 0
|
算法 安全 Java
并发策略-CAS算法
对于并发控制而言,我们平时用的锁(synchronized,Lock)是一种悲观的策略。
143 0
|
算法 Java 安全
2.JUC线程高级-原子变量与CAS算法
1.变量原子性引发的问题 这里我们通过一个很经典的案例i++来分析下原子性问题 int i = 10; i = i++; 此时i的值为:10 执行完i++后为什么结果是10,原因是因为i++操作,jvm底层实际是分为以下三步:(读-改-写) int temp = i; i = i + 1; i = temp; 2.
1216 0
|
30天前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真
|
1月前
|
算法
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
23 2

热门文章

最新文章