介绍 CAS

技术是为了解决问题而生的,通过 CAS 我们可以以无锁的方式,保证对共享数据进行 “读取 - 修改 - 写回” 操作序列的正确性。

CAS 是乐观锁设计思想的实现。CAS 的思想是:在“读取 - 修改 - 写回”操作序列中,先读取并修改数据,写回数据前先判断读取数据后的这段时间内数据是否发生变化(共享变量的当前值是否是我们的期望值):

  • 如果在此期间数据没有发生变化(共享资源的当前值是我们的期望值),那么就把修改后的值写回
  • 如果在此期间其他的线程修改了数据,数据发生了变化(共享资源的当前值不是我们的期望值),那么就放弃本次写回操作,再基于最新的数据进行修改然后重试,避免发生数据更新丢失

CAS 更加底层的实现依赖于 CPU 提供的特定指令,具体根据体系结构的不同还存在着明显区别。比如,x86 CPU 提供 cmpxchg 指令;而在精简指令集的体系架构中,则通常是靠一对指令(如“load and reserve”和“store conditional”)实现的。在大多数处理器上 CAS 都是非常轻量级的操作,这也是其优势所在。

Java 的 CAS 操作

CAS 依赖于 Unsafe 类提供的一些底层能力,进行底层操作。

/**
* Atomically update Java variable to x if it is currently
* holding expected.
* @return true if successful
*/
public final native boolean compareAndSwapInt(Object o, long offset,
int expected,
int x);

在调用 compareAndSwap() 方法时,我们需要传入需要修改的共享变量、对象偏移量、我们期望的变量当前值、要写回的值。如果变量的当前值和我们的期望值相等,则写回成功,返回 true,否则写回失败,返回 false。

Unsafe 类是 Java 提供的一个操作内存的非安全类,操作对象和对应的变量来完成 CAS 操作。显然 Unsafe 类过于底层,调用 Unsafe 类的方法不是大多数应用场景的最好选择。目前 Java 提供了两种公共 API,可以实现 CAS 操作:

  • 一种是 Atomic 原子类。Atomic 包中的类对 Unsafe 类进行了封装,使我们可以更方便的使用 CAS 操作。Atomic 包提供了常见的原子性数据类型,甚至是引用、数组等相关原子类型和原子更新操作工具。
  • 还有一种是 Variable Handle API,它源自于JEP 193,提供了各种粒度的原子或者有序性的操作等。

CAS 的优劣局限

CAS 的优点:在大多数处理器上 CAS 都是非常轻量级的操作。


CAS 的局限:

  • CAS 操作是针对一个共享变量的,如果需要解决多个变量的原子性问题,建议还是使用互斥锁方案。
  • 存在 ABA 问题:当一个线程在进行 CAS 操作时,另一个线程可能会在此期间修改了同一个共享变量的值,然后又将其改回原来的值。这种情况下,CAS 操作就无法检测到共享变量值的变化,从而导致 ABA 问题。如果我们仅仅在写回数据前判断数值是 A,可能导致不合理的写回操作。针对这种情况,Java 提供了 AtomicStampedReference 工具类,通过为对象引用建立类似版本号(stamp)的方式,来解决 ABA 问题,保证 CAS 的正确性。
  • 如果有大量的线程同时对一个共享变量进行 CAS 操作,竞争过于激烈的情况下,尝试进行 CAS 操作的线程只会白白消耗处理器资源,而不会做任何有价值的工作,这就会带来性能的浪费。

Java的CAS操作的更多相关文章

  1. 多线程之:java的CAS操作的相关信息

    一:锁机制存在的性能问题? 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁). 锁机制存在以下问题:(1)在多线程竞争下,加锁.释放锁会导 ...

  2. Java自定义cas操作

    java Unsafe工具类提供了一个方法 public final native boolean compareAndSwapObject(Object var1, long var2, Objec ...

  3. Java并发--Java中的CAS操作和实现原理

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...

  4. java面试-CAS底层原理

    一.CAS是什么? 比较并交换,它是一条CPU并发原语. CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B.当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什 ...

  5. 【Java并发编程实战】-----“J.U.C”:CAS操作

    CAS,即Compare and Swap,中文翻译为"比较并交换". 对于JUC包中,CAS理论是实现整个java并发包的基石.从整体来看,concurrent包的实现示意图如下 ...

  6. 深入浅出 Java Concurrency (5): 原子操作 part 4 CAS操作

    在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁). 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度 ...

  7. Java乐观锁实现之CAS操作

    介绍CAS操作前,我们先简单看一下乐观锁 与 悲观锁这两个常见的锁概念. 悲观锁: 从Java多线程角度,存在着“可见性.原子性.有序性”三个问题,悲观锁就是假设在实际情况中存在着多线程对同一共享的竞 ...

  8. java高并发系列 - 第21天:java中的CAS操作,java并发的基石

    这是java高并发系列第21篇文章. 本文主要内容 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库乐观锁的一个常见示例 使用ja ...

  9. Java并发指南3:并发三大问题与volatile关键字,CAS操作

    本文转载自互联网,侵删   序言 先来看如下这个简单的Java类,该类中并没有使用任何的同步. 01 final class SetCheck { 02 private int  a = 0; 03 ...

  10. 【Java并发011】原理层面:CAS操作全解析

    一.前言 volatile关键字是Java51个关键字中用的比较少的一个,它是一个与多线程并发的关键字,但是实际开发中,一般不会用到,使用synchronize+wait()+notify()/not ...

随机推荐

  1. Javaweb学习笔记第七弹

    Maven依赖范围 对于Maven的安装配置等环境准备问题,可详细参考我的前几篇博客, 网址1:https://www.cnblogs.com/liuzijin/p/16654344.html 网址2 ...

  2. Android错误之--Error retrieving parent for item: No resource found that matches the given name 'Theme.A

    改正错误 (虽然内容较少,但是还是选择单独占用一篇) 这个错误,可以说是困扰了我好久,然后就看到可以改变一下使用的Android版本,改成Android 4.0,然后就去试了试,发现真的就好了耶! 就 ...

  3. 为什么 C# 可能是最好的第一编程语言

    纵观神州大地,漫游中华互联网,我看到很多人关注为什么你应该开始学习JavaScript做前端,而对blazor这样的面向未来的框架有种莫名的瞧不起,或者为什么你应该学习Python作为你的第一门编程语 ...

  4. ROS话题通信C++(附launch启动方式)

    ROS话题通信C++(附launch启动方式) 创建工作空间 mkdir -p topic_ws/src cd topic_ws catkin_make 设置环境变量 source ./devel/s ...

  5. Scanner进阶用法

    Scanner进阶用法 判断是否为整数,浮点数 package charpter2; import java.util.Scanner; public class Scanner3 { public ...

  6. 常用ADB命令使用方法

    移动端操作流程 在设置中找到关于手机(或关于平板电脑) 连续点击版本号5次 在系统和更新中点击开发者选项 打开USB调试功能 PC端操作流程 打开cmd或powershell 移动到adb.exe所在 ...

  7. Sokit(TCP/UDP调试工具)

    下载:http://www.winwin7.com/soft/56522.html#xiazai Sokit中文版是一款免费开源的TCP / UDP 测试(调试)工具,它主要可以用于接收和发送TCP/ ...

  8. Install Ansible on CentOS 8

    环境准备: 1.至少俩台linux主机,一台是控制节点,一台是受控节点 2.控制节点和受控节点都需要安装Python36 3.控制节点需要安装ansible 4.控制节点需要获得受控节点的普通用户或r ...

  9. Redhat7/CentOS7 网络配置与管理(nmtui、nmcli、GNOME GUI、ifcfg文件、IP命令)

    Redhat7/CentOS7 网络配置与管理(nmtui.nmcli.GNOME GUI.ifcfg文件.IP命令) 背景:作为系统管理员,需要经常处理主机网络问题,而配置与管理网络的方法和工具也有 ...

  10. CentOS8 搭建Kubernetes

    CentOS8 搭建Kubernetes 主机名 IP 组件 k8s-master 192.168.40.128/24 kubeadm.kubelet.kubectl.docker-ce k8s-no ...