乐观锁: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

宇树机器人G1二次开发:语音对话、打断与激活功能实现指南

宇树机器人G1是一款功能强大的四足机器人,其开放的SDK和API为开发者提供了广阔的二次开发空间。其中,语音交互是提升机器人智能化水平和用户体验的关键功能。本文将详细介绍如何在宇树机器人G1上进行二次开发,实现。语音打断允许用户在机器人说话时随时中断并输入新指令,这是提升交互自然度的关键功能。三大核心功能,帮助你构建更自然、更智能的人机交互系统。语音识别是将用户的语音输入转换为文本的过程。识别文本后,需要理解用户意图并生成回复。将文本回复转换为语音输出。

m0_52645558的博客 662

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

golang 线上事故

golang 线上事故 最近公司要做大促的一些活动。并且单量,qps持续上涨。之前使用的是django python 语言做的一个服务端。目前已经部署的国家里面最多的国家会有300+个实例。大促期间还可能会增加一个实例数。这么多的实例部署,回滚的时间都会特变长,除了问题也不好定位。并且如此多的一个机器,连接数* 实例数也会导致DB等其他服务扛不住这么大的并发。所以决定上go服务解决性能问题。 ...

lcf枫的博客 1537

基于STM32的多普勒雷达测速

基于多普勒雷达传感器,以STM32单片机为主控芯片,根据不同模块检测距离的不同,使用不同多普勒雷达传感器实现对远近距离车辆行驶速度及方向的测量。 1、基础知识 无线电探测和测距,是用无线电(电磁波)方法发现目标并测定其空间位置的装置。随着雷达技术的发展,现代雷达不仅可以对目标进行定位,还可以测量目标的速度、对目标进行成像甚至测量目标的大小和材料特性。所有利用雷达波来检测物体速度的原理,其理论基础皆源自于“多普勒效应”,...

weixin_52801934的博客 6315

Java并发编程 - CAS 底层剖析

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

J-Proton博客 371

用Python搞定超效率SBM模型:从数据清洗到结果可视化全流程指南

本文详细介绍了如何使用Python实现超效率SBM模型,从数据清洗到结果可视化的全流程指南。超效率SBM模型作为传统DEA的进化版本,能有效处理非期望产出(如环境污染)并对高效单元进行精细排序。通过实战案例和代码示例,帮助读者掌握这一先进模型的Python实现技巧,提升效率评估的准确性和可视化效果。

silver的专栏 649

深入理解CAS和常用原子类

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

Minor的Java技术博客 1156

Python爬虫实战:从巨潮网批量抓取上市公司年报JSON数据

网络爬虫作为自动化数据采集的核心技术,其原理是通过模拟浏览器行为向服务器发送HTTP请求并解析响应,从而高效获取结构化信息。在金融数据分析领域,这项技术价值尤为突出,能够将研究人员从繁琐的手工数据收集中解放出来,聚焦于更高阶的模型构建与价值挖掘。典型的应用场景包括上市公司财务研究、市场趋势分析和风险预警系统开发。本文以Python的requests库为核心工具,详细解析如何通过分析巨潮资讯网的JSON数据接口,构建一个稳定、高效的上市公司年报数据采集管道,并重点探讨了接口逆向、分页爬取、PDF文件下载等关键

weixin_42529366的博客 1234

4.Simulink基础建模操作——加减乘除运算

加减乘除运算

FPGA/MATLAB学习教程/源码/项目合作开发 9549

Java:CAS(乐观锁)

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

青春年少不知疼的博客 199

uniapp [安卓苹果App端] - 实现微信支付功能+拉起微信付款支付后返回本app页面,详解uniApp如何唤起本机微信app并跳转到支付页面全流程及示例源码(uniapp实现微信支付,可打包)

uni-app项目在APP端使用微信支付功能,uniapp前端实现微信支付,uniapp开发安卓App对接微信支付,uniapp苹果ios唤起微信支付,uniapp调用微信支付uniapp开发app-调用微信支付,uniapp开发安卓苹果app如何接入微信支付,前后端应该怎么做,UniApp中实现微信支付功能,支付报错,调起失败没响应,uniapp苹果微信支付唤起实现,app唤起微信支付,拉起微信支付,uniapp中唤醒微信进行支付并返回app,uniApp调起微信支付失败报错,全网最详细的uniapp微信

🏆 前端领域优质创作者 1万+

Java :CAS 乐观锁

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

weixin_44364684的博客 219

java项目反编译工具记录,共计6个工具

java项目反编译工具记录,共计6个工具

橙-极纪元-JJYCheng 1801

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

乐观锁:CAS算法

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

lilian9215的博客 153

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

java开发:乐观锁CAS机制

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

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

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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、付费专栏及课程。

余额充值