CAS个人理解

CAS原理讲解(个人理解) CAS原理: 比较并交换:(compareAndSet) 主物理内存的值与线程的期的望值一致的话, 就进行修改;不同的话,就不能进行修改; package CAS; import java.util.concurrent.atomic.AtomicInteger; public class CASdemo01 { public static void main(String[] args) { //物理内存中值: 5 AtomicInteger atomicInt 阅读详情

CAS是什么?

CAS(Compare And Swap)是一条cup并发原语,其本质是比较并交换。

CAS实例

public class CASDemo {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(5);
        atomicInteger.compareAndSet(5, 2019);
        System.out.println(atomicInteger.get());
        atomicInteger.compareAndSet(2019, 2000);
        System.out.println(atomicInteger.get());
        }
  }

CAS的底层

自旋锁 + Unsafe类

什么是Unsafe类

由于java无法直接访问的底层系统内存,不像c语言那样可以直接通过指针,访问变量的存储地址。java需要通过本地方法访问底层系统数据存储地址,而Unsafe类弥补了 这一局限性,相当于一个后门。Unsafe提供了很多的native方法可以直接访问操作特定内存的数据。与c语言的指针类似。

什么是自旋锁

自旋锁是一种为了保护共享资源而提出的一种锁机制。

代码原理如下:

 public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

在上面的代码中
var1 就是对象进行操作的对象引用
var2 是该对象引用在内存的偏移量,也就是起始地址
var5 是期望值
var5 + var4 是待更新的值
这段代码的含义就是根据共享变量的存储地址获取该变量的值,判断该变量的值是否等于期望值,如果相等则将待更新主内存中该变量的值为最新的值。反之,继续进行比较,直到主内存中的值和期望值一致为止。
CAS并发原语体现在Java语言就是Unsafe类的各个方法,java条用Unsafe类的方法,JVM会自动帮我们实现CAS的汇编指令,这是一种完全依赖于硬件的功能,通过它体现了原子性操作,CAS是系统原语,属于操作系统指令,由若干条指令组成的代码块,执行必须是连续性,中间不能被中断。

CAS的缺点:
1、循环时间长,内存消耗大;
如果线程数量比较多的话,CAS请求失败会一直循环下去,这样的话CPU的开销会比较大。
2、只能对一个共享变量进行原子性的操作
3、会出现ABA问题。

什么是ABA问题?
由于CAS无法对主内存共享变量的操作记录,比如,更改次数,是否更改。这容易让一个线程将给A修改成B,而另一个线程又将B修改成A造成CAS多次执行的问题。也就是开头和结尾是一样的,中间过程发生了变化。
原子引用
原子引用AtomicReference是保证基本类型的原子性,对于一个类而言,可以使用原子引用进行封装。

AtomicReference<User> userAtomic =  new AtomicReference<>();

如何解决ABA问题
ABA问题的本质就是通过CAS多次改变了主内存的共享变量的值,而最终又改为最初的值。头尾一样,中间的操作对于其他线程来说是不可知的,这可能会造成CAS的多次执行。
而想要解决ABA问题的办法就是让其他线程能够知道这个变量中间有被更改过,我们只在变量每一次被修改时添加一个记录就可以解决了这个一个问题。
AtomicStampedReference 在原有的AtomicReference上添加了版本号的概念。
使用案例

public class ABADemo { //ABA解决问题,AtomicStampedReference

    static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1);
    public static void main(String[] args) {
        new Thread(()->{
            atomicReference.compareAndSet(100, 101);
            atomicReference.compareAndSet(101, 100);
        }, "t1").start();
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(1);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(atomicReference.compareAndSet(100, 100) + "\t" + atomicReference.get());
        },  "t2").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }

        System.out.println("*******************演示ABA的解决********************");
        new Thread(()->{
            int stamp = atomicStampedReference.getStamp(); //获取版本号
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + stamp);
            try { TimeUnit.SECONDS.sleep(1); }catch (InterruptedException e){ e.printStackTrace();}
            atomicStampedReference.compareAndSet(100, 101, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + atomicStampedReference.getStamp());
            atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + atomicStampedReference.getStamp());
        }, "t3").start();

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + atomicStampedReference.getStamp());
            try{ TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e){e.printStackTrace();}
           boolean result =  atomicStampedReference.compareAndSet(100, 2019, stamp, stamp + 1);
            System.out.println(Thread.currentThread().getName() + "修改成功?" + result + "当前最新版本号" + atomicStampedReference.getStamp());
            System.out.println(Thread.currentThread().getName() + "当前线程实际最新值" + "\t" + atomicStampedReference.getReference());
        }, "t4").start();
    }
}

使用时间戳原子引用,当某个线程在修改值时,发现虽然内存中的值和预期值一样,但是由于版本号已经发生了该改变,所以修改失败,这时候需要重新获取该变量的版本号和变量的值再进行修改,并标记新的为新的版本。

揭秘CAS:深入理解与应用解析 在并发编程中,Compare-And-Swap(CAS)机制作为一种无锁算法,凭借其高效性和避免线程阻塞的优势,受到广泛关注。CAS不仅在底层实现上有着重要地位,还在实际开发中发挥着关键作用。本文将从CAS的工作原理、在Java中的实现及其增强机制来回顾和加深理解一下CAS。 阅读详情

相关推荐

比较几款国际主流的电子元器件及物料清单管理软件 – 工具汇总

Arenasolution 老牌的基于云计算物料清单管理软件,bom.com就是他们家的,10天免费试用,功能被分成4个不同的产品, 和传统ERP功能上有重叠,偏向于物流生产规划,一定程度可以取代ERP的生产规划模块,平均价格70美元/月/席位。网页客户端,不支持离线   SiliconExpert 曾经的老牌物料清单管理软件,后被Arrow 收购,14天免费试用,功能被分成4个不同的产品

u012062784的专栏 7235

【并发编程】CAS到底是什么

CAS是Compare-And-Swap(比较并交换)的缩写,是一种轻量级的同步机制,主要用于实现多线程环境下的无锁算法和数据结构,保证了并发安全性。它可以在不使用锁(如synchronized、Lock)的情况下,对共享数据进行线程安全的操作。

陈宝子的博客 9268

提供一个微信投票刷票的js代码

最近几天,有个朋友找我去写一个脚本帮他 在微信上刷票、微信投票刷票,我大概看了一下,本次微信投票刷票其实就是根据微信的openid来限制,每个openid只能投三次票的限制。上图可以看出,其实只要openid,和toopenid即可,openid是自己的微信id,toopenid是投票对象的微信id,那我们定时修改openid即可给某一个人刷投票。把这段代码复制到浏览器F12之后的console里,直接回车即可开始微信投票刷票(刷新或关闭浏览器即可停止刷票)//生成随机的ip地址。

qq_858865388专业提供快速微信投票教程攻略和方法的博客 2万+

CAS的原理和使用

你只需要记住:CAS是靠硬件实现的从而在硬件层面提升效率,最底层还是交给硬件来保证原子性和可见性实现方式是基于硬件平台的汇编指令,在intel的CPU中(X86机器上),使用的是汇编指令cmpxchg指令。核心思想就是:比较要更新变量的值V和预期值E(compare),相等才会将V的值设为新值N(swap)如果不相等自旋再来。可以丢入泛型中Class AtomicReference案例int age;

weixin_43869741的博客 2835

NE5532A与JRC4580在低噪声音频电路设计中的关键应用

本文深入探讨了经典运算放大器NE5532A与JRC4580在低噪声音频电路设计中的核心应用。文章从噪声模型分析入手,阐述了针对低阻抗信号源时,如何利用这两款BJT输入运放的低电流噪声特性进行优化设计。通过对比两者参数与实战守则,为设计高保真音频前级、耳机放大等电路提供了从原理图到PCB布局的完整低噪声解决方案。

weixin_29295541的博客 328

深入解析 TDA4VM/VH R5F 核中断机制:VIC 与非 VIC 模式下的实战对比与优化

本文深入解析了TI TDA4VM/VH平台中ARMv7-R架构R5F核的两种中断处理机制:VIC模式与非VIC模式。通过对比硬件自动跳转与软件向量表分发的核心流程、实战代码示例及性能差异,为开发者提供了基于实时性、灵活性与调试需求的选择指南和优化建议,帮助构建更稳定的嵌入式系统。

weixin_29159441的博客 98

SSO(单点登录)实施中遇到的几个问题

单点登录应用中,遇到如下的几个问题:1.超时问题;2.jsessionid问题;3.单点退出时有时子系统未能正常退出;4.有些请求路径不需要单点登录过滤器拦截;5.不同应用服务实现可能要求SSO客户端做适应性改造。我们具体分析一下,并提出解决方法。 1.超时问题         我们提供的CAS开源单点登录SSO组件,它部署节点主要有2个:SSO服务器(部署内容为一个web应用)、应用系统

yan_dk的专栏 1万+

ddr3ip核心_DDR3 IP 核配置

DDR3 控制器 IP 核2.DDR3 IP核配置点击 Flow Navigator 面板下的“Project Manager -->IP Catalog”。 在“Memories & Storage Elements -->Memory Interface Generators”分类展开后,可以看到名为“Memory Interface Generator (MIG 7 ...

weixin_33049919的博客 2935

深入理解Java多线程CAS比较并交换的底层原理

一.多线程环境下的自增操作 我们都知道在多线程情况下 i++ 的自增操作不是原子性的,因为它分为三个步骤: 取得i的值 将i的值+1 将新值写回内存 所以我们会使用JUC包下的AtomicInteger类来进行int的原子操作: public final int addAndGet(int delta) { return unsafe.getAndAddInt(this, va...

atomatom98的博客 471

Vue3项目实战:集成h265webjs打造高性能Web端H.265播放器

本文详细介绍了如何在Vue3项目中集成h265webjs库,构建高性能的Web端H.265播放器。通过封装播放器管理模块、利用Vue3组合式API优雅管理生命周期,并提供了从环境准备、核心集成到进阶优化的完整实战指南,有效解决了浏览器原生不支持H.265解码的难题,显著降低视频流带宽占用。

weixin_29016833的博客 363

【报错解决】彻底解决 MySQL 登录报错 ERROR 1045 (28000)

MySQL 报错 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 通常是由于用户名或密码错误、权限不足、服务未启动或配置文件异常导致的。通过检查并确认密码、重置 root 用户密码、授予完整权限、校验配置文件以及确保 MySQL 服务正常运行,可以彻底解决该问题。掌握这一流程不仅能够恢复 root 登录,还能保障数据库的安全性与稳定性。

博客 1750

Java中CAS详解

在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。 (2)一个线程持有锁会导致其它所有需要此锁的线程挂起。 (3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。 volatile是不错的机制

jayxu无捷之径的博客 20万+

【系统分析师】高分论文:论软件需求验证方法及应用

本文以某清算平台建设项目为例,探讨了软件需求验证方法的应用。该项目旨在隔离银行与支付公司的直接通信,满足央行监管要求。作为系统分析师,作者通过需求测试和需求评审两种方法确保需求质量。需求测试采用概念测试用例提前发现问题;需求评审通过正式与非正式形式多方确认需求。项目结合邮件评审、专家会议等方式,最终形成完善的需求文档。平台上线后运行良好,验证了需求管理的重要性。该案例表明,科学的需求验证是项目成功的关键保障。

数据知道的博客 8125

对CAS的一点个人理解

在Java中,JDK 1.5之后可以使用CAS(Compare-and-Swap)操作。CAS的思想就是:先将旧期待值与主内存中值作比较,如果相同,那么就接受新的值,否则就不进行任何操作,这种处理过程是一个原子操作。 CAS帮助我们实现非阻塞同步策略,这是一种乐观并发策略,乐观就是指它总是假设其他线程不会打扰自己,所以会先进行操作,如果有冲突,再采取一定措施,比如一直重试直到成功为止。这种策略的...

Shelby Lee的博客 412

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

CAS的个人理解

什么是CAS CAS是Compare And Swap即比较并交换的缩写。 CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。 CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作(因为调用了CPU提供的指令,intel CPU中为cmpxchg)。 CAS一般是配合无限循环使用的。 CAS的三个问题 ABA问题 循环时间开销很大 只能保证一个变量的原子操作 ABA问题 因为CAS需要在操作值的时候

Nana77mi的博客 232

VC中sqlite的使用

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

CAS算法个人理解

一、描述 在日常的开发中,经常会出现多个线程去同时操作一个变量的情况。在这种情况下,我们经常会将此变量加上synchronized修饰符,来保证同一时间内只能有一个线程去访问修改该变量,但这样其他的县城都必须挂起,效率非常低。所以出现了一种新的思想:也就是CAS算法。 CAS算法全名为Compare And Swap 算法,即比较-替换算法。 这种算法有三个变量,内存地址的值V,旧的预期值A...

StartLine 285

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

cas_个人理解

原网址:https://www.cnblogs.com/gossip/p/5651379.html 总结的非常好的文章,值得分享! 分为三个部分: 1、Cas服务器(用于验证用户是否正确) 1、用户信息存在服务端,其它客户端应用程序修改用户信息后需要同步到服务端 2、用户信息一般存储在服务端的数据库中,加密及验证算法Cas提供默认方法 2、Cas客户端(和应用程序合为一体) 3、客户端(一般是用户...

qq_38949960的博客 414

Cas_个人理解

分为三个部分: 1、Cas服务器(用于验证用户是否正确) 1、用户信息存在服务端,其它客户端应用程序修改用户信息后需要同步到服务端 2、用户信息一般存储在服务端的数据库中,加密及验证算法Cas提供默认方法 2、Cas客户端(和应用程序合为一体) 3、客户端(一般是用户使用的web浏览器) 名词解释 http://www.coin163.com...

weixin_33910460的博客 134

JUC并发编程学习笔记——CAS个人理解

即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。

程哥哥的一亩三分地 338

什么是CAS单点登录

早上遇到别人说的CAS单点登录问题,俺在一旁一头雾水,就看了一下什么是CAS单点登录,由于度娘上基本没有关于什么CAS单点登录,都是说怎么部署的,所以写一下这篇东西记录一下个人理解。 场景:由于一个公司的web应用有很多,每个应用的登录系统都不一样,当同一个用户访问一个公司的应用时,我们不可能要让他登录多次(ps:例如腾讯有很多应用,QQ,空间,邮箱,游戏等等),CAS单点登录就是为了...

u010314099的博客 233

CAS理解和说明

然而,ABA问题是一个潜在的问题,即在CAS操作过程中,一个变量的值被修改两次后又恢复到了原来的值,导致CAS误判为没有发生变化,这个问题就叫ABA问题。完成的,所以CAS操作是原子的,就可以在一定程度上回避线程安全问题,所以我们在解决线程安全问题除了加锁之外,又有了一个新思路。此时的value值变成1,但是CAS的返回值为true,所以oldValue的值仍然为0。在这里最特别的是,上述这个CAS的过程,并非是通过一段代码实现的,而是通过。我们假设内存中的原始数据V,旧的预期值A,需要修改的新值B。

m0_62055442的博客 1889

Java中的CAS理解

Java中的CAS理解CAS是什么?CAS能做什么?CAS在java中的应用CAS有没有什么不好的隐患呢?1、首先就是经典的ABA问题2、长时间自旋非常消耗资源3、只能保证一个共享变量的原子操作。 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。 (2)一个线程持有锁会导致其它所有需要此锁的线程挂起。 (3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致

@龙猫的博客 2457

CAS详解,如何理解CAS!

CAS是英文单词Compare and Swap的缩写,翻译过来就是比较并替换。 CAS机制中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。 更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。 我们看一个例子: 在内存地址V当中,存储着值为10的变量。 2. 此时线程1想把变量的值增加1.对线程1来说,旧的预期值A=10,要修改的新值B=11. 3. 在线程1要提交更新之前,另一个线程2抢先一步,把内存地址V中的变量值率先更新

Pumpkin's Blog 2240

CAS的理解

CAS 的全称 Compare-And-Swap,它是一条 CPU 并发操作。 jdk1.5开始,并发包里提供了一些类支持原子操作,,如 AtomicInteger,这些原子包装类还提供了有用的工具方法,比如以原子的方式对当前对象进行+1或者-1;Java并发框架包中有一些并发框架使用了CAS自旋锁的方式来实现原子操作,CAS虽然解决了原子操作的问题,但是仍然存在三大问题。ABA问题,循环时间长开...

qq_35529931的博客 1104
上一篇: 解决IDEA写代码卡顿问题
下一篇: 震惊! Docker启动tomcat访问竟然报404?看看这位小伙子如何处理!
小码林marlin
博客等级 码龄9年 30粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值