乐观锁:CAS

面试二十七、 CAS和Atomic 通过硬件提供的原子指令实现无锁的原子操作,确保在多线程环境下的数据一致性和线程安全。通过使用内存顺序,可以进一步控制操作的可见性和顺序,以满足不同的并发编程需求。CAS只能保证变量的原子性,不能保证变量的内存可见性。CAS获取共享变量的值时,需要和volatile配合使用,来保证共享变量的可见性。而并发量过高,会导致自旋重试耗费大量的CPU资源。CAS只能保证单个变量的原子操作,要保证多个变量的原子操作,可以使用锁机制。,但可以通过将版本号和指针组合在一起实现类似的效果。来保证多个变量的原子操作的示例。 阅读详情

一、CAS 简述

CAS:比较并交换(CompareAndSwap),应用于多线程并发场景中,实现了无锁状态下的线程安全。CAS 避免了使用互斥锁,当多个线程同时进行 CAS 指令更新同一个变量时,只有其中一个线程能够操作成功,而其他线程都会更新失败。但此时更新失败的线程并不会被阻塞,而是还可以再次 CAS 尝试。

二、Unsafe 类

sun.misc.Unsafe 是 Java 提供的一个可直接操作内存空间的类。其特点:

1)、不受 JVM 管理,使用 Unsafe 操作内存无法被 JVM GC,需要手动 GC,此时容易出现内存泄漏。

2)、Unsafe 的很多方法必须提供原始地址(内存地址)和 被替换对象的地址,偏移量要自己计算(其提供的有计算偏移量的方法),如果出现问题将会导致整个JVM 实例崩溃。

3)、直接操作内存,所以速度更快,在高并发的条件之下能够很好地提高效率。

Unsafe 类中有大量的被 native 关键字修饰的方法,这些方法是由 C/C++ 实现,底层调的是 C/C++ 的库函数,还有一些基于 native 方法封装的其他方法,整个Unsafe中的方法大致可以归结为以下几类:初始化操作、操作对象属性、操作数组元素、线程挂起和恢复和 CAS 机制。

Unsafe 类中的 compareAndSwap方法:

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

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

    public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

 

三、CAS 原理

CAS 有三个操作数:内存值 V、预期值 A、要修改的值 B。仅当预期值 A 和当前的内存值 V 相同时,才将内存值修改为 B ,否则什么都不做。

1)、Unsafe 类中的所在方法都是native修饰的,也就是送 Unsafe 类中的方法都直接调用操作系统底层资源执行相应任务,故可以直接比较内存值和期望值。value 值被 volatile 修饰后保证了其可见性,一旦发生偏移就会通知本地内存。

2)、变量 valueOffset ,表示该变量值在内存中的偏移地址,因为 Unsafe 就是根据内存偏移地址获取数据的。

3)、变量value 用 volatile修饰,保证了多线程之间内存的可见性

    /**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

 

 /*
    var1 Atomiclntegler对象本身。
    var2该对象值得引用地址。
    var4 需要变动的数量。
    var5是用过var1 var2找出的主内存中真实的值。
    用该对象当前的值与var5比较:
    如果相同,更新var5+var4并且返回true,如果不同,继续取值然后再比较,直到更新完成。
*/
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

compareAndSwapInt 的 JNI 本地实现代码:

CAS 缺点:

1)、循环时间长开销很大,unsafe 底层如果不匹配成功会一直 do-while 下去(如下图代码),一直不成功会造成很大的 cpu 开销)

2)、只能保证一个共享变量的原子操作。(一次只能保证一个对象)

3)、可能产生ABA问题

超越并发瓶颈:CAS与乐观锁的智慧应用 synchronized 是 Java 内置的同步机制,依赖 JVM 实现,通过进入和退出监视器锁(Monitor Lock)来保证线程的安全性。在高并发情况下,线程可能会频繁地在 BLOCKED 状态和 RUNNABLE 状态之间切换,导致用户态和内核态的频繁切换,从而影响性能。 CAS和乐观锁作为两种重要的并发控制机制备受关注。CAS机制直接利用硬件保证原子性,而乐观锁则基于乐观的思想进行并发控制。本文将学习这两种机制的原理、应用及性能特点来进行体会 阅读详情

相关推荐

乐观锁思想在Java中的实现:CAS

在Java中,乐观锁可以使用CAS(Compare and Swap)操作来实现。CAS是一种原子操作,它比较内存中的值与预期值,只有在值相等的情况下才会进行更新。乐观锁思想在Java中的实现主要依赖CAS操作,它允许多个线程同时读取和修改共享变量,从而提高了并发性能。然而,CAS操作也有一些限制,例如ABA问题和自旋开销。因此,在实际应用中,我们需要综合考虑具体情况来选择适合的并发控制策略。方法会比较当前值与预期值,如果相等则进行更新,否则继续循环。在上面的示例中,我们使用。方法中,我们使用一个。

ScriptCharm的博客 167

底层分析为什么CAS不保证可见性

在CPU缓存架构,CAS只保证比较和交换这个操作是原子的,不保证值的可见性,每个CPU都有自己的缓存,CAS成功后值只更新到当前CPU的缓存中。

xweiran的博客 1138

win11 labelme 汉化菜单

【代码】win11 labelme 汉化菜单。

一直记录 1169

cas-----保证数据一致性,cas操作间的可见性,但不保证JMM内存可见性

先来个示例: import lombok.Data; @Data public class CasTestObjecy { private int value = 0; } package com.fen.fou; import org.springframework.objenesis.instantiator.util.UnsafeUtils; import sun.misc.Unsafe; public class CasTest2 { static CasTest

beiduofen2011的专栏 1207

告别效率低谷:用ADS仿真手把手教你设计高回退Doherty功放(附1:2非对称案例)

本文详细解析了如何使用ADS仿真设计高回退Doherty功放,特别针对1:2非对称架构进行深入探讨。通过优化功率分配比、峰值管开启阈值等关键参数,显著提升功放在9dB回退点的效率至75%以上,适用于LTE等高PAPR信号场景。文章还提供了ADS仿真环境搭建、参数优化及工程化设计的实用技巧。

weixin_33743248的博客 453

别让IO口保护二极管坑了你!实测讲解单片机电流倒灌的三种典型症状与防护

本文深入解析单片机电流倒灌的三大典型症状与防护方案,重点分析STM32等单片机在ADC采样异常、系统假死和通信速率异常中的表现。通过实测数据和电路设计建议,提供从基础二极管隔离到专业隔离器件的分级防护策略,帮助工程师有效预防和解决电流倒灌问题。

weixin_29280219的博客 344

Java并发编程 - CAS 底层剖析

Java并发编程 - CAS 底层剖析 由volatile关键字可知,他可以保证JMM内存模型的可见性和有序性(禁止指令重排序)但是不能保证原子性,导致线程安全问题,我们可以加synchronized关键字来解决但是对于有些业务来说,synchronized太重了开销太大,所以我们可以用JUC包下的原子操作系列Atomic操作类,提供了操作的原子性。在底层的实现原理还是CAS。 CAS:...

J-Proton博客 371

自动批量安装加载cran, bioconductor和github三个平台的所有的R包

自动批量安装加载cran, bioconductor和github三个平台的所有的R包

qq_40073899的博客 560

深入理解CAS和常用原子类

针对一个变量,首先对变量进行修改,然后比较它的内存值和期望值进行比较,如果相同则将修改后的新值覆盖内存,否则什么都不处理。CAS的比较和交换两个步骤通过CPU的一个汇编指令执行,具有原子性,通常CAS可以看做是一种乐观锁的机制。Java的CAS机制是通过unsafe类来进行API调用完成,例如对int变量的CAS操作,可...

Minor的Java技术博客 1156

Amesim应用篇-电芯等效电路模型标定

为了使计算模型更加准确,在有电芯实验测试数据的情况下,依据现有的实验数据对Amesim中的电池等效电路模型进行标定。标定的目的是为了获得更加符合项目实际情况的电芯等效电路模型,标定完的电芯可以用于搭建PACK模型,也可以用于其他虚拟实验。本文以充电标定为例,进行介绍。放电标定与充电一致。

2201_75375391的博客 1213

Multisim14.0仿真应用设计(三十九)74LS183 高速全加器应用仿真

74LS183是一种高速全加器,可以同时执行四位二进制数的加法运算。它的输入端包括两个4位二进制数和一个进位信号,输出端则为一个4位二进制数和一个进位信号。

zhusl6688的博客 3851

Java:CAS(乐观锁)

本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助。 什么是悲观锁、乐观锁?在java语言里,总有一些名词看语义跟本不明白是啥玩意儿,也就总有部分面试官拿着这样的词来忽悠面试者,以此来找优越感,其实理解清楚了,这些词也就唬不住人了。 synchronized是悲观锁,这种线程一旦得到锁,其他需要锁的...

青春年少不知疼的博客 199

大厂硬件笔试机试题ASIC设计方向-卷3

本文提供了30道硬件工程师机试题目,涵盖数字逻辑、模拟电路、CMOS和信号处理等核心领域。选择题和判断题均配有详细解析,重点考察Verilog编程、CMOS特性、触发器设计、采样定理等知识点。题目难度适中但覆盖面广,如Verilog中阻塞/非阻塞赋值的区别、CMOS静态功耗来源、Nyquist采样定理、通用逻辑门判断等。备考建议强调掌握逻辑门设计、Verilog时序电路编写和CMOS特性理解。这些题目反映了华为等大厂硬件机试的典型考查内容,通过系统复习可有效提升机试成绩,为后续面试奠定基础。

启芯硬件的博客 542

Java :CAS 乐观锁

转自 简书 本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助。 什么是悲观锁、乐观锁?在java语言里,总有一些名词看语义跟本不明白是啥玩意儿,也就总有部分面试官拿着这样的词来忽悠面试者,以此来找优越感,其实理解清楚了,这些词也就唬不住人了。 synchronized是悲观锁,这种线程一旦得到锁,其他需要锁的线程就挂起的情况就是悲观锁。 CAS操作的就是乐观锁,每次不加锁而是假设没有冲突而去完成某项操作,如果

weixin_44364684的博客 219

共享单车数据抓取与分析:使用Python爬虫抓取共享单车使用数据与地图信息

通过本篇博客,我们展示了如何使用Python爬虫抓取共享单车的使用数据和地图信息,并通过简单的数据分析得出有价值的见解。在实际应用中,数据的收集与分析不仅能帮助城市管理者更好地规划单车站点,还能为用户提供更精准的单车使用体验。未来,我们可以将此分析与机器学习模型相结合,进一步预测单车的使用趋势,优化调度算法,实现更加智能的共享单车管理。

2201_76125261的博客 2204

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

乐观锁:CAS算法

乐观锁:CAS算法 CAS算法理解 对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 ...

lilian9215的博客 153

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

java开发:乐观锁CAS机制

先来说说什么是悲观锁、乐观锁: 悲观锁:总是假设最坏的情况,每次操作数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞,直到它拿到锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁:总是假设最好的情况,每次操作数据的时候都认为别人不会修改。所以不会上锁,其他线程依然是可以访问,但是在更新的时候会判断一...

一个程序员-二白的博客 664

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java cas原理_乐观锁:CAS 算法

在并发编程中,我们大多数情况下都是显式地通过加锁来保证线程安全。这里我们来介绍一种在无锁条件下多线程变量同步的方法——CAS(Compare And Swap,比较与交换)算法悲观锁、乐观锁在介绍CAS算法之前,我们先了解两个概念——悲观锁、乐观锁。首先需要明确的是它们并不是指代某个具体的锁,而是指两种不同的并发控制策略悲观锁当一个线程使用数据时,悲观锁总是认为其它线程也会过来修改这个数据。为了保...

weixin_39959236的博客 169

彻底理解Java并发:乐观锁与CAS

本篇内容包括:悲观锁与乐观锁的概述、CAS(Compare And Swap)比较并交换的介绍、非阻塞算法与ABA问题,以及对 Java 中 CAS 的实现解读(AtomicInteger 对 CAS 的实现,Unsafe 类简介)。

栗筝i的博客 6526

乐观锁:超卖和CAS的思考

对比直接使用悲观锁,比如,将“比较和交换”这一部分代码上锁,作为临界区,使多线程互斥访问(这段代码相当于具有了原子性)。其所能达到的效果,也是等同于CAS的。而CAS能够实现无锁编程,是依赖于原子性的。也就是说,基于CAS思想实现的乐观锁,和悲观锁很像,都是对临界区代码实现了原子性。底层的CAS函数,就是一条CPU指令,自然是原子性的使用互斥锁,只有一个线程可以访问临界区,其他线程阻塞在Redis中利用Lua脚本实现。

wjd89ddd的博客 815

Java并发深度总结:乐观锁CAS

执着于理想,纯粹于当下。 内容1.悲观锁与乐观锁2.CAS的实现 1.悲观锁与乐观锁 悲观锁:悲观锁认为被它保护的数据是极其不安全的,每时每刻都有可能变动。获取共享资源的线程对共享资源加锁,其它线程被阻塞,其他只能等待锁被释放才可以执行。 Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁:乐观锁和悲观锁对应,它认为数据的变动不会太频繁。因此,所以不会对共享资源上锁。线程在更新共享资源时,会去校验在此期间有没有其他线程去更新这个数据。 Java.

白日梦想家的博客 657

浅谈:什么是乐观锁CAS

其实因为 AtomicInteger 类也在 rt.jar 包下面的,所以 AtomicInteger 类就是通过 Bootstrap 根类加载器进行加载的, Unsafe 类具体实现就得看 hotspot 源码, unsafe.cpp,C++ 的代码就不在具体在这里分析,感兴趣的同学可以去看看,从代码里可以看到 CAS 的实现离不开处理器的支持,根据当前处理器的类型来决定是否为 cmpxchg 指令添加 lock 前缀。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。评论留言少 BUG!

2501_94671711的博客 201
上一篇: Merge Into 快速更新大量数据
下一篇: CAS中ABA问题及解决
West Money
博客等级 码龄9年 7粉丝 48原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值