java CAS

CAS
  • 在高并发场景,可以使用加锁 或者CAS来保证原子性,但是加锁是很重量级的操作,CAS类似于乐观锁
  • CAS ( Compare and swap )比较并交换,是实现并发算法时常用到的技术,包含三个操作数:内存位置、预期原值、更新值
  • 执行CAS操作的时候,将内存位置中的值与预期原值比较
    • 如果匹配,会将该位置的值更新为新值,
    • 如果不匹配就不会做任何操作,或者重试,这种重试被称为自旋,多个线程同时执行CAS操作,只有一个会成功
  • CAS 是JDK提供的非阻塞原子操作,通过硬件保证了比较-更新的原子性
  • CAS 是一种系统原语,原语属于操作系统用于范畴,由若干条指令组成,用于完成某个功能,原语的执行必须是连续的,在执行过程中不允许被中断,所以说CAS是一条CPU的原子指令,不会造成数据不一致的问题
  • JDK提供的CAS机制,在汇编层级会禁止变量两侧的指令优化,然后使用 cmpxchg(比较并交换) 指令比较并更新变量值
  • 执行 cmpxchg 指令的时候,会判断当前系统是否为多核系统,
    • 如果是就给总线加锁,只有一个线程可以对总线加锁成功,加锁成功后执行CAS操作
    • 所以CAS的原子性实际上是CPU实现独占的,比起synchronized,CAS的排他时间要短很多,多线程情况下性能会更好
Unsafe类:
  • Unsafe类是CAS的核心类,由于java无法直接访问底层,需要通过本地的 native 方法来访问,
  • Unsafe想当与一个后门,基于该类可以直接操作特定内存的数据,内部的操作可以向C的指针一样直接操作内存,该类的方法基本都是native的,可以直接调用操作系统底层资源执行任务
  • 但是实际工作中不要自己去使用 Unsafe类,容易导致内存混乱
  • 如下,三个类似的方法,以第一个为例,参数分别为:
    • var1 是操作的对象
    • var2 是操作对象中属性地址的偏移量
    • var4 期望的值
    • var5 要修改的新值
  • 核心思想就是比较内存中的值与预期原值进行比较,相等就更新为新值,例如:
    • A、B两个线程都想要变更共享变量的值,各自都先读到主内存中的原值
    • A执行较快,先完成计算,写回时判断主内存中的值和原值一样,就把计算得到的新值写回
    • 这时B也执行完了,写回时判断主内存中的值和原值不一样,就放弃本次操作,这里可以加上自旋让B重新执行一次,这样在多线程情况下,两次计算结果就都不会丢失了

在这里插入图片描述

CAS自旋锁
  • CAS利用CPU的指令保证了操作的原子性,达到锁的效果
  • 自旋锁也就是获取锁失败的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,直到成功获取锁,或者超时,放在CAS就是执行一个CAS操作,不断的去执行CAS操作,直到CAS操作被成功执行
  • 这样的好处是减少了线程上下文的切换,缺点是循环会消耗CPU

示例:不通过 synchronized 和 lock ,就实现了锁的功能,自己实现自旋锁

public class Caslock {
    
    //是否加锁,初始值为 false,也就是未加锁
    private AtomicBoolean atomicBoolean =new AtomicBoolean(false);
    
    public void lock(){
        System.out.println(Thread.currentThread().getName()+",尝试加锁");
        //原子布尔的值是否是false,是就加锁,把值改为true,不是就释放锁
        while (!atomicBoolean.compareAndSet(false,true)){
            //不是false,加锁失败,由其他线程先加了锁,这里就需要等待
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        System.out.println(Thread.currentThread().getName()+",加锁成功");
    }
    public void unLock(){
        //解锁,把值设为 false
        atomicBoolean.compareAndSet(true,false);
        System.out.println(Thread.currentThread().getName()+",释放锁");
    }
}


    private static void testCasLock() throws Exception{
        Caslock caslock = new Caslock();
        new Thread(()->{
            caslock.lock();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            caslock.unLock();
        },"线程A").start();

        Thread.sleep(500);
        new Thread(()->{
            caslock.lock();
            caslock.unLock();
        },"线程B").start();
    }


CAS的缺点

  • 循环时间太长的话,开销会很大

  • ABA问题

    • 例如A、B 两个线程,都拿到相同的初始值,A把值加1后写回,然后减1后又写回
    • 此时B才执行完,尽管线程B的CAS操作成功,但是这样丢失了A的两次操作,所以仅仅只比较内容,是线程不安全的

想要解决ABA问题,需要加上版本号或者时间戳

  • AtomicStampedReference:流水号的戳记引用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/299645.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LVGL的List控件的触摸按键和实体按键的处理

在LVGL的List控件使用过程中,虽然通过触摸按键选择item,但是有些场景需要实体按键选取item,但是LVGL 的V8.3中没有像Emwin那样有函数选择list item的函数。LVGL中List引入了Group的概念,把列表项都添加到同一个group中。然后通过更…

Linux Capabilities 基础概念与基本使用

目录 1. Linux capabilities 是什么? 2. capabilities 的赋予和继承 线程的 capabilities Permitted* 允许 Effective* 有效 Inheritable* 遗传 Bounding(集合) Ambient 文件的 capabilities Permitted Inheritable Effective 3…

2.4 DEVICE GLOBAL MEMORY AND DATA TRANSFER

在当前的CUDA系统中,设备通常是带有自己的动态随机存取存储器(DRAM)的硬件卡。例如,NVIDIA GTX1080具有高达8 GB的DRAM,称为全局内存。我们将互换使用全局内存和设备内存这两个术语。为了在设备上执行内核,…

通过聚道云软件连接器实现钉钉与自研主数据系统的完美融合

客户介绍 某知名高校,拥有数千名教职工,日常管理涉及大量的人员异动信息。该高校设有多个学院和研究所,涵盖了工、理、管、文等多个学科领域。该高校是一所充满活力和潜力的学府,致力于为学生提供优质的教育资源和多元化的学习环…

广义零样本学习综述的笔记

1 Title A Review of Generalized Zero-Shot Learning Methods(Farhad Pourpanah; Moloud Abdar; Yuxuan Luo; Xinlei Zhou; Ran Wang; Chee Peng Lim)【IEEE Transactions on Pattern Analysis and Machine Intelligence 2022】 2 conclusion Generali…

三种主流流协议的浏览器播放解决方案

三种主流流协议的浏览器播放解决方案 流协议介绍 主流的流协议(streaming protocol)包括HLS、RTMP、RTSP,下面依次介绍下三种视频流。 HLS HLS(Http Live Streaming) 是一个由苹果公司提出的基于HTTP的流媒体网络传输协议&…

微信小程序 引导地址授权 获取位置信息 uniapp

概述 获取位置信息,需要保证是否授权位置信息,有几个条件是导致无法授权的原因 (1)微信应用未授权定位设置 (2)首次进入小程序未授权位置信息 (3)小程序之前阻止过授权位置信息 &…

SpringBoot整合JUNIT5单元测试+Mockito

目录 第一章、快速了解JUnit单元测试1.1)单元测试是什么1.2)为什么使用JUnit单元测试 第二章、快速使用JUnit5框架2.1)在pom文件中导入依赖2.2)新建测试类2.3)新建一个简单的测试方法 第三章、测试框架提供的注解和方法…

【设计模式】备忘录模式

一起学习设计模式 目录 前言 一、概述 二、结构 三、案例实现 1、 “白箱”备忘录模式 2、“黑箱”备忘录模式 四、优缺点 五、使用场景 总结 前言 【设计模式】备忘录模式——行为型模式。 一、概述 备忘录模式提供了一种状态恢复的实现机制,使得用户可以…

Android studio BottomNavigationView 应用设计

一、新建Bottom Navigation Activity项目: 二、修改bottom_nav_menu.xml: <itemandroid:id="@+id/navigation_beijing"android:icon="@drawable/ic_beijing_24dp"android:title="@string/title_beijing" /><itemandroid:id="@+i…

小游戏实战丨基于PyGame的消消乐小游戏

文章目录 写在前面PyGame消消乐注意事项系列文章写在后面 写在前面 本期内容&#xff1a;基于pygame实现喜羊羊与灰太狼版消消乐小游戏 下载地址&#xff1a;https://download.csdn.net/download/m0_68111267/88700193 实验环境 python3.11及以上pycharmpygame 安装pygame…

jenkins忘记admin密码

jenkins忘记admin密码&#xff0c;重置密码&#xff1a; 1.找打jenkins目录下面的config.xml [rootVM-0-15-centos .jenkins]# find ./* -name config.xml ./config.xml [rootVM-0-15-centos .jenkins]# pwd /root/.jenkins删除下面的这部分内容&#xff1a; [rootVM-0-15-c…

Android开发编程从入门到精通,安卓技术从初级到高级全套教学

一、教程描述 本套教程基于JDK1.8版本&#xff0c;教学内容主要有&#xff0c;1、环境搭建&#xff0c;UI布局&#xff0c;基础UI组件&#xff0c;高级UI组件&#xff0c;通知&#xff0c;自定义组件&#xff0c;样式主题&#xff1b;2、四大组件&#xff0c;Intent&#xff0…

【UML】第15篇 状态机图

目录 一、状态机图的定义 二、应用场景 三、绘图符号的说明 四、语法 五、例图 一、状态机图的定义 状态机图&#xff08;State Machine Diagram&#xff09;是UML中的一种行为图&#xff0c;它描述了一个对象在其生命周期内的状态变化。状态机图通过展示对象在不同状态下…

技术学习|CDA level I 描述性统计分析(数据的描述性统计分析)

技术学习|CDA level I 描述性统计分析&#xff08;数据的描述性统计分析&#xff09; 数据的描述性统计分析常从数据的集中趋势、离散程度和分布形态3个方面进行。 一、集中趋势 集中趋势是指数据向其中心值靠拢的趋势。测量数据的集中趋势&#xff0c;主要是寻找其中心值。…

跨站脚本攻击漏洞XSS绕过22种方式总结

XSS漏洞简介 跨站脚本攻击在目前这个时间节点还是属于一个排位比较高的漏洞&#xff0c;在OWASP TOP10 2021中隶属于注入型漏洞&#xff0c;高居TOP3的排位&#xff0c;可见这个漏洞的普遍性。跨站脚本攻击的学习中我们主要需要明白的是跨站的含义&#xff0c;以及XSS的核心。…

Vue3-39-路由-导航异常的检测 afterEatch 与 编程式导航之后的订阅动作

说明 本文主要是介绍一下 路由的后置守卫 afterEatch 的一个重要的作用 &#xff1a; 就是检测路由异常信息。 它的实现方式是 通过第三个参数来返回的。 而且&#xff0c;它的异常检测是全局的。导航的异常有以下三种类型&#xff1a; aborted : 在导航守卫中 被拦截并返回了…

1月最新阿里云服务器租用价格表_轻量61元_ECS99元一年

2024年1月最新阿里云服务器租用价格表&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;2核4G4M带宽轻量服务器一年165元12个月、2核4G服务器30元3个月&#xff0c;云服务器ECS可以选择经济型e实例、通用…

学习笔记——C++运算符之算术运算符

C中运算符包含诸多种类&#xff0c;其中有&#xff1a;算术运算符&#xff0c;赋值运算符&#xff0c;比较运算符和逻辑运算符 每一种运算符及其作用如下表所示&#xff1a; 一&#xff0c;算术运算符1&#xff0c;加减乘除 其中&#xff0c;“”&#xff0c;“-”运算符既可…

QT上位机开发(数据库sqlite编程)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 编写软件的时候&#xff0c;如果用户的数据比较少&#xff0c;那么用json保存是非常方便的。但是一旦数据量大了之后&#xff0c;建议还是用数据库…