什么是乐观锁和悲观锁?CAS又是什么鬼?

    悲观锁是将资源锁住,等一个之前获得锁的线程释放锁之后,下一个线程才可以访问。

    乐观锁采取了一种宽泛的态度,通过某种方式不加锁来处理资源,可以使用版本号version和cas算法实现,性能较悲观锁有很大的提高。乐观锁适用于多读的应用类型,这样可以提高吞吐量

    CAS算法

    CAS全拼又叫做compareAndSwap,从名字上的意思就知道是比较交换的意思

    它包含 3 个参数 CAS(V,E,N),V表示要更新变量的值,E表示预期值,N表示新值。仅当 V值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做两个更新,则当前线程则什么都不做。最后,CAS 返回当前V的真实值。

    它涉及到三个操作数:内存值、预期值、新值

    cas是一种基于锁的操作,而且是乐观锁。在java中锁分为乐观锁和悲观锁。悲观锁是将资源锁住,等一个之前获得锁的线程释放锁之后,下一个线程才可以访问。而乐观锁采取了一种宽泛的态度,通过某种方式不加锁来处理资源,比如通过给记录加version来获取数据,性能较悲观锁有很大的提高。

    CAS机制的优缺点

    (1)优点

    一开始在文中我们曾经提到过,cas是一种乐观锁,而且是一种非阻塞的轻量级的乐观锁,什么是非阻塞式的呢?其实就是一个线程想要获得锁,对方会给一个回应表示这个锁能不能获得。在资源竞争不激烈的情况下性能高,相比synchronized重量锁,synchronized会进行比较复杂的加锁,解锁和唤醒操作。

    (2)缺点

    缺点也是一个非常重要的知识点,因为涉及到了一个非常著名的问题,叫做ABA问题。假设一个变量 A ,修改为 B之后又修改为 A,CAS 的机制是无法察觉的,但实际上已经被修改过了。这就是ABA问题

    乐观锁的缺点:

    1、ABA问题

    解决办法:

    JDK 1.5 以后的 AtomicStampedReference 类就提供了此种能力,其中的compareAndSet 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

    2、循环时间长导致cpu的开销大

    自旋CAS如果一直没有获取锁或一直等待。

    解决办法:

    如果JVM支持处理器的PAUSE指令,两个作用:1、延长流水线执行指令(时间取决于实现的版本),使CPU不会消耗过多的资源;2、避免退出循环时因内存顺序冲突引起的CPU流水线被清空。

    3、只能保证一个共享变量的原子操作

    CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时CAS 无效

    解决办法:

    JDK1.5后AtomicStampedReference类确保引用对象之间的原子性,可以把多个变量放在一个对象里来进行 CAS 操作.所以我们可以使用锁或者利用 AtomicReference 类把多个共享变量合并成一个共享变量来操作。

    本文作者:好名字
    原文链接:https://www.cuizb.top/myblog/article/1639579500
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY 3.0 CN协议进行许可。转载请署名作者且注明文章出处。

    更多文章和干货请关注公众号

    posted @   Java技术债务  阅读(91)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · DeepSeek “源神”启动!「GitHub 热点速览」
    · 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
    · C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
    · DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
    · 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
    点击右上角即可分享
    微信分享提示
    💬
    评论
    📌
    收藏
    💗
    关注
    👍
    推荐
    🚀
    回顶
    收起
    1. 1 404 not found REOL
    404 not found - REOL
    00:00 / 00:00
    An audio error has occurred.