IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 乐观锁实现之CAS算法分析 -> 正文阅读

[数据结构与算法]乐观锁实现之CAS算法分析

在介绍 CAS 之前,先来了解下什么是乐观锁。

乐观锁(Optimistic Lock)是指对于数据冲突保持一种乐观态度,操作数据时不会对数据加锁,只有到数据提交的时候才通过某种机制来验证数据是否存在冲突。

可以通过使用版本号CAS 算法进行实现,本篇博客主要介绍?CAS 算法的概念,以及对 CAS 算法的实现原理进行分析。

什么是 CAS 算法

CAS:Compare and Swap,即比较再交换,其算法公式如下:

函数公式:CAS(V,E,N)

CAS 操作需要我们提供一个期望值,当期望值与当前线程的变量值相同时,说明还没有线程修改该值,当前线程就可以进行修改,也就是执行 CAS 操作。

但如果期望值与当前线程的变量值不符,则说明该值已被其他线程修改,此时不执行更新操作,但可以选择重新读取该变量并尝试再次修改,也可以放弃操作。

CAS 的实现原理

对 java.util.concurrent.atomic 包下的原子类 AtomicInteger 中的 compareAndSet 方法进行分析,可以发现最终调用的是 sum.misc.Unsafe 这个类。

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(long expect, long update) {
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }

Unsafe 类本身是不安全的,它为了速度,在 Java 的安全标准上做出了一定的妥协。Unsafe 的 CAS 依赖的是 JVM 针对不同的操作系统实现的 Atomic::cmpxchg 函数。

Atomic::cmpxchg 函数使用了汇编的 CAS?操作,并使用 CPU?硬件提供的 lock 信号保证其原子性的实现。

CAS 的优缺点

优点

CAS 是非阻塞的轻量级乐观锁,通过 CPU 指令实现。在资源竞争不激烈的情况下,synchronized 重量锁会进行比较复杂的加锁、解锁和唤醒操作,而 CAS 不会加锁,性能高。

缺点

CPU开销大

在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量却又一直更新不成功,会给 CPU带来很大压力。

不能保证代码块的原子性

CAS 机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用 synchronized 同步锁了。

?除了以上两个缺点,CAS 还可能会出现 ABA 的问题,那么 ABA 问题又是什么呢?

CAS 中的 ABA 问题

如果一开始位置 V 得到的旧值是 A ,当进行赋值操作时再次读取发现仍然是 A ,并不能说明变量没有被其它线程改变过,有可能是其它线程将变量改为了 B,后来又改回了 A。

?

对于 ABA 问题,主要有两种解决方案:

使用版本号

在变量前面追加版本号,每次变量更新的时候把版本号加一,也就是说,之前的 A-B-A 就会变成?1A - 2B - 3A。

使用并发包的原子类

java.util.concurrent.atomic 包下提供了一个可处理 ABA 问题的原子类 AtomicStampedReference。其 compareAndSet 方法首先会检查当前引用是否等于预期引用,且当前标志是否等于预期标志。

如果全部相等,则以原子方式将该引用的该标志的值设置为给定的更新值。

CAS 的使用场景

  • Atomic 开头的实现类

以 Atomic 开头的实现类的底层都使用了 CAS 算法。

  • 自旋锁

自旋锁是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程不会阻塞,而是将循环等待,不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。可以看成是一个不断自动重试的乐观锁,它是 CAS 算法的一种锁机制的实现。

  • 令牌桶限流器

系统以恒定的速度向桶内增加令牌,每次请求前从令牌桶里面获取令牌,只有获取到令牌就才可以进行访问。

当令牌桶内没有令牌的时候,就会拒绝提供服务。其中的限流器就是通过使用 CAS 算法来维护多线程环境下对令牌的增加和分发的。

参考了如下博客,非常感谢:

Java并发编程之CAS算法

java中的cas - 知乎

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:26:26  更:2021-09-26 10:28:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:40:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码