Marvel-Site Marvel-Site
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)

Marvel

吾必当乘此羽葆盖车
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)
  • Java

    • Java基础

    • Java进阶

    • Java容器

    • Java并发编程

      • 并发编程基本概念
      • 多线程
      • 创建多线程的方法
      • 比较与交换CAS
        • CAS
        • Unsafe类
        • CAS的问题
      • Java对象头与Monitor监视器
      • Java主流锁
      • synchronized关键字
      • volatile关键字
      • 线程池
      • 原子类Atomic
      • LockSupport工具
      • 抽象队列同步器AQS
      • ThreadLocal深度理解
      • 多线程循环打印代码
      • 线程等待和唤醒的三种方式
      • ReentrantLock非公平锁的源码分析
    • Java虚拟机

    • 常见面试题

  • 计算机基础

  • 框架|中间件

  • 架构

  • 后端
  • Java
  • Java并发编程
Marvel
2022-07-19
目录

比较与交换CAS

# 比较与交换CAS

# CAS

CAS 全称 Compare And Swap,比较与交换,是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。java.util.concurrent包中的原子类就是通过 CAS 来实现了乐观锁。

CAS 算法涉及的三个操作数:

  • 需要读写的内存值 V
  • 进行比较的值 A
  • 要写入的新值 B

当 V=A 时,CAS 通过原子方式用新值B来更新V的值,否则不会执行任何操作。一般情况下,“更新”是一个不断重试的操作。

乐观锁的主要实现方式就是 CAS

# Unsafe类

在Java中,Unsafe 类是 CAS 的核心类,存在于 sun.misc 包中,由于 Java 方法无法直接访问底层系统,需要本地(Native)方法来访问,Unsafe 相当于一个后门,其内部方法操作可以像 C 的指针一样直接操作内存。

Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务。

CAS,是一条CPU并发原语。它的功能是判断内存某个位置是否位预期值,如果是则更改为新的值,这个过程是原子的。JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能,通过它实现了原子操作。

原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成数据不一致问题。

public final class Unsafe {
	...
    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);
    ...
}
1
2
3
4
5
6
7

# CAS的问题

  1. ABA问题,CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但实际上是有变化的。ABA问题的解决思路就是在变量前面添加版本号,每次变量更新的时候都把版本号加一,这样变化过程就从“A-B-A“编程”1A-2B-3A“。
  2. 循环时间长开销大,CAS操作如果长时间不成功,会导致其一直自选,给CPU带来非常大的开销。
  3. 只能保证一个共享变量的原子操作,对一个共享变量执行操作时,CAS能够保证原子操作,但是多个共享变量操作时,CAS是无法保证操作的原子性。
编辑 (opens new window)
上次更新: 2023/08/20, 21:21:52
创建多线程的方法
Java对象头与Monitor监视器

← 创建多线程的方法 Java对象头与Monitor监视器→

最近更新
01
位运算
05-21
02
二叉树
05-12
03
Spring三级缓存解决循环依赖
03-25
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Marvel
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式