返回顶部
首页 > 资讯 > 后端开发 > JAVA >【Java基础】CAS (Compare And Swap) 操作
  • 835
分享到

【Java基础】CAS (Compare And Swap) 操作

java开发语言 2023-08-23 07:08:42 835人浏览 薄情痞子
摘要

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、使用场景四、原理五、优劣5.1 缺点

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端移动开发人工智能等,希望大家多多支持。

一、导读

我们继续总结学习Java基础知识,温故知新。

二、概览

CAS其实就是Compare And Swap的一个缩写,顾名思义就是比较并交换,其实就是把当前值与你预期的值进行一个比较,是一种用于在多线程环境下实现同步功能的机制。

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。
在这里插入图片描述

CAS是原子性的操作(读和写两者同时具有原子性),是让CPU比较内存中某个值是否和预期的值相同,如果相同则将这个值更新为新值,不相同则不做更新.
对比交换是一条CPU的原子指令,其实现方式是基于硬件平台的汇编指令

CAS操作是原子性的,所以多线程并发使用CAS更新数据时,可以不使用

使用volatile关键字可以保证可见性和有序性,但是却没有原子性,比如a++,引入cas就可以解决多线程的原子性问题。

CAS配合volatile来实现许多高并发
在这里插入图片描述

三、使用场景

Java中利用CAS的乐观锁、原子性的特性高效解决了多线程的安全性问题。

CAS这种方式适用于并发量不高的情况。

四、原理

实现方式是通过借助C/C++调用CPU指令完成的,是一条CPU的原子指令,依赖于系统。

CAS的实现主要在JUC中的atomic包,存放在 java.util.concurrent.atomic 类路径下
如:自增长 AtomicInteger 等

Java中的CAS操作的执行依赖于Unsafe类,我们看下AtomicInteger的代码:

public class AtomicInteger extends Number implements java.io.Serializable {    private static final Unsafe unsafe = Unsafe.getUnsafe();        private volatile int value;          public AtomicInteger(int initialValue) {        value = initialValue;    }    public final boolean compareAndSet(int expect, int update) {        return unsafe.compareAndSwapint(this, valueOffset, expect, update);    }    }

CAS配合volatile来实现多线程可见性有序性和原子性。

再看下Unsafe类

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

我们进入Unsafe类的native方法compareAndSwapInt,调用UnSafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令,这是一种完全依赖于硬件的功能,通过它实现了原子操作。

由于CAS是一种系统原语,原语属于操作系统用于范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS操作是一条CPU的原子指令,不会造成所谓的数据不一致的问题,所以说CAS是线程安全的。

假如一个线程操作数据,干了一半活,累了,想要去休息。(貌似今天的线程体质都不太好)。于是它记录下当前数据的状态(就是数据的值),回家睡觉了。 醒来后打算继续接着干活,但是又担心数据可能被修改了,于是就把睡觉前保存的数据状态拿出来和现在的数据状态比较一下,如果一样,说明自己在睡觉期间,数据没有被人动过(当然也有可能是先被改成了其它,然后又改回来了,这就是ABA问题了),那就接着继续干。如果不一样,说明数据已经被修改了,那之前做的那些操作其实都白瞎了,就干脆放弃,从头再重新开始处理一遍。

所以CAS这种方式适用于并发量不高的情况,也就是数据被意外修改的可能性较小的情况。如果并发量很高的话,你的数据一定会被修改,每次都要放弃,然后从头再来,这样反而花费的代价更大了,还不如直接加锁呢。

五、优劣

5.1 缺点:

  1. 循环时间长开销大(CAS自旋操作):当内存地址V与预期值B不相等时会一直循环比较,直到相等
  2. 只能保证一个共享变量的原子操作,不能保证代码块的原子性。
  3. 存在ABA问题

并发1(上):获取出数据的初始值是A,后续计划实施CAS乐观锁,期望数据仍是A的时候,修改才能成功
并发2:将数据修改成B
并发3:将数据修改回A
并发1(下):CAS乐观锁,检测发现初始值还是A,进行数据修改
并发1在修改数据时,虽然还是A,但已经不是初始条件的A了,
中间发生了A变B,B又变A的变化,此A已经非彼A,数据却成功修改,
可能导致错误,这就是CAS引发的所谓的ABA问题。

优化ABA问题:
“版本号”的比对,一个数据一个版本,版本变化,即使值相同,也不应该修改成功。
很好解决,再加一个版本号字段就行了,并规定只要修改数据,必须使版本号加1。

5.2 优点

  • 没有引用锁的概念,并发量不高情况下提高效率
  • 减少线程上下文切换

六、 推荐阅读

【Java基础】原子性、可见性、有序性

【Java基础】java可见性之 Happens-before

【Java基础】java-android面试Synchronized

【Java基础】java-android面试-线程状态

【Java基础】线程相关

【Java基础】java 异常

【Java基础】java 反射

【Java基础】java 泛型

【Java基础】java注解

【Java基础】java动态代理

【Java基础】Java SPI

【Java基础】Java SPI 二 之 Java APT

【Java基础】 jvm 堆、栈、方法区 & java 内存模型

【Java基础】volatile关键字

【Java基础】CountDownLatch

来源地址:https://blog.csdn.net/fumeidonga/article/details/131542090

--结束END--

本文标题: 【Java基础】CAS (Compare And Swap) 操作

本文链接: https://lsjlt.com/news/378379.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 【Java基础】CAS (Compare And Swap) 操作
    关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、使用场景四、原理五、优劣5.1 缺点...
    99+
    2023-08-23
    java 开发语言
  • Java编程cas操作全面解析
    CAS 指的是现代 CPU 广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。这个指令会对内存中的共享数据做原子的读写操作。简单介绍一下这个指令的操作过程:首先,CPU 会将内存中将要被更改的数据与期望的值做比较。然后,当这两个值相等...
    99+
    2023-05-31
    java cas 多线程
  • 【基础操作】1.表操作
    -- 1.基本表操作表 drop table user1; create table user1( id   &nb...
    99+
    2024-04-02
  • mysql基础操作
    查看有哪些库:show databases;进入某个库:use 库名;进入库之后查看有哪些表:show tables;查看某张表的结构:desc 表名;查看某张表的所有内容:select * from 表名;创建一个库:...
    99+
    2015-11-17
    mysql基础操作
  • MySQL -- 基础操作
    CREATE DATABASE 数据库名称; 查看数据库: # 查看所有数据库 SHOW DATABASES; 创建数据库: # 选择一个数据库/切换至xxx数据库 USE 数据库名称; 创建数据库...
    99+
    2015-11-15
    MySQL -- 基础操作
  • MongoDB基础操作
    MongoDB增删改查操作 MongoDB数据库服务启动和关闭 net start mongodb net stop mongodb 数据库连接 先使用npm install mongoose安装mongoose依赖,之后使用mongoo...
    99+
    2017-01-10
    MongoDB基础操作 数据库入门 数据库基础教程 数据库 mysql
  • Java实现单链表基础操作
    关于链表 链表是有序的列表链表是以节点的方式来存储每个节点包含data域,next域(指向下一个节点)分带头节点的链表和没有头节点的链表 定义一个节点: package linke...
    99+
    2024-04-02
  • MariaDB的基础操作
    1、创建数据库MariaDB [(none)]> CRRATE DATABASE test1;    #创建一个名为te...
    99+
    2024-04-02
  • RMAN基础操作(一)
    Recoverymanager(RMAN)是ORACLE 8i后提供的备份,恢复工具。它能够备份整个数据库或数据库部件,其中包括表空间,数据文件,控制文件和归档文件。RMAN可以按要求存取和执行备份和恢复。...
    99+
    2024-04-02
  • 【PG】PG基础操作
    mark笔记 1 登录 [postgres@hostnfsd ~]$ psql     --默认登录用户是当前系统用户,并默认登录和当前系...
    99+
    2024-04-02
  • python基础操作---tuple
    1 #coding:utf-8 2 3 tup1 = ('physics', 'chemistry', 1997, 2000); 4 tup2 = (1, 2, 3, 4, 5 ); 5 tup3 = "a", "b", "...
    99+
    2023-01-31
    操作 基础 python
  • python基础操作---string
    1 #coding:utf-8 2 3 var1 = 'Hello World!' 4 5 print var1[::] 6 print len(var1) 7 print var1[0:len(var1)] 8 p...
    99+
    2023-01-31
    操作 基础 python
  • Python-selenium基础操作
    一. selinum优势页面级测试,模拟用户真实操作强大library,支持页面元素各类操作多浏览器支持(chrome,firefox,ie)多语言支持(python,java,C#,php,ruby)二. 需要安装软件firefox  f...
    99+
    2023-01-31
    操作 基础 Python
  • Java基础之文件和目录操作
    目录一、前言二、构造方法三、文件元数据四、文件操作五、目录操作六、总结一、前言 文件和目录操作最终是与操作系统和文件系统相关的,不同系统的 实现是不一样的,但Java中的java.i...
    99+
    2024-04-02
  • Java Io File文件操作基础教程
    目录File 类概述File对象文件操作File静态方法获取各种路径路径整合获取classpath路径 (常用)获取Tomcat的bin目录常用功能创建目录创建文件判断文件或文件夹是...
    99+
    2024-04-02
  • Java基础之二叉搜索树的基本操作
    目录一、二叉搜索树插入元素二、搜索指定节点三、删除节点方式一四、删除节点方式二五、运行结果一、二叉搜索树插入元素 class Node { int v...
    99+
    2024-04-02
  • 数据库基础操作
    显示查询结果使用排序功能 order by [列名] desc; #desc 表示降序,asc 表示升序例:select * from 表名 where ID = '00...
    99+
    2024-04-02
  • MySQL基础操作命令
    MySQL基础操作命令1、 查看MySQL进程ps -ef|grep mysql |grep -v grep2、 查看MySQL端口ss -lnt | grep 33063、 ...
    99+
    2024-04-02
  • GolangDefer基础操作详解
    目录defer的执行顺序defer与return谁先谁后函数的返回值初始化有名函数返回值遇见defer情况defer遇见panicdefer中包含panicdefer下的函数参数包含...
    99+
    2024-04-02
  • python之LIST基础操作
    1,创建列表>>> list1=['a','b','c','d'] >>> list2=[1,2,3,4] >>> list3=['a','b','c',1,2,3]2,访问列表中的值&...
    99+
    2023-01-31
    操作 基础 python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作