1.CAS

CAS 即 Compare and Swap ,它体现的一种乐观锁的思想,比如多个线程要对一个共享的整型变量执 行 +1 操作:

// 需要不断尝试
while(true) {   int 旧值 = 共享变量 ; // 比如拿到了当前值 0  int 结果 = 旧值 + 1; // 在旧值 0 的基础上增加 1 ,正确结果是 1  /*  这时候如果别的线程把共享变量改成了 5,本线程的正确结果 1 就作废了,这时compareAndSwap 返回 false,重新尝试,直到:    compareAndSwap 返回 true,表示我本线程做修改的同时,别的线程没有干扰  */  //这里其实是把共享变量的值与旧值做比较,如果相同,就可以安全的把结果写入共享变量if( compareAndSwap ( 旧值, 结果 )) {     // 成功,退出循环  }
}

CAS对共享变量可以不用加锁。
**获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。**结合 CAS 和 volatile 可以实现无 锁并发,适用于竞争不激烈、多核 CPU 的场景下

  • 因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一
  • 但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响
    线程陷入阻塞,会涉及到线程的上下文切换,这样就严重降低了效率。

CAS 底层依赖于一个 Unsafe 类来直接调用操作系统底层的 CAS 指令,下面是直接使用 Unsafe 对象进 行线程安全保护的一个例子

import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class TestCAS {    public static void main(String[] args) throws InterruptedException {DataContainer dc = new DataContainer();        int count = 5;Thread t1 = new Thread(() -> {for (int i = 0; i < count; i++) {                dc.increase();}});t1.start();t1.join();System.out.println(dc.getData());}
}
class DataContainer{private volatile int data;static final Unsafe unsafe;static final long DATA_OFFSET;static {try {// Unsafe 对象不能直接调用,只能通过反射获得Field theUnsafe =Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);unsafe = (Unsafe) theUnsafe.get(null);}catch(NoSuchFieldException | IllegalAccessException e) {throw new Error(e);}try {// data 属性在 DataContainer 对象中的偏移量,用于 Unsafe 直接访问该属性。//方便定位data的地址。DATA_OFFSET=unsafe.objectFieldOffset(DataContainer.class.getDeclaredField("data"));} catch (NoSuchFieldException e) {throw new Error(e);}}public void increase(){int oldValue;while(true) {// 获取共享变量旧值,可以在这一行加入断点,修改 data 调试来加深理解oldValue = data;    // cas 尝试修改 data 为 旧值 + 1,如果期间旧值被别的线程改了,返回 false/*第一个参数当前DataContainer对象,第二个参数偏移量。对前面两个信息我们知道,针对哪个字段做compareandSwap。后面的参数就是旧值和新值,它首先会把oldValue与共享变量的当前值做比较。如果两个不一致,表明修改失败,然后我就重新进入while循环,直到旧值和共享变量的值一致了。然后compareandswap才会返回true,并且新值更新到共享变量data里去。if条件成立,while就结束了    */        if (unsafe.compareAndSwapInt(this, DATA_OFFSET, oldValue, oldValue + 1)) {return;            }}    }public void decrease() {int oldValue;while(true) {oldValue = data;if (unsafe.compareAndSwapInt(this, DATA_OFFSET, oldValue, oldValue - 1)){                              return; }}}

2 乐观锁与悲观锁

CAS 是基于乐观锁的思想:乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系, 我吃亏点再重试呗。
synchronized 是基于悲观锁的思想:悲观的估计,得防着其它线程来修改共享变量,我上了锁 你们都别想改,我改完了解开锁,你们才有机会

3 原子操作类

juc(java.util.concurrent)中提供了原子操作类,可以提供线程安全的操作,例如:AtomicInteger、 AtomicBoolean等,它们底层就是采用 CAS 技术 + volatile 来实现的。 可以使用 AtomicInteger 改写之前的例子:

// 创建原子整数对象
private static AtomicInteger i = new AtomicInteger(0);public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int j = 0; j < 5000; j++) {i.getAndIncrement();  // 获取并且自增  i++ //                i.incrementAndGet();  // 自增并且获取  ++i        }    });Thread t2 = new Thread(() -> {for (int j = 0; j < 5000; j++) {i.getAndDecrement();  // 获取并且自增  i++            } });t1.start();t2.start();t1.join();t2.join();System.out.println(i);
}

JVM学习-CAS与原子类相关推荐

  1. atomic原子类实现机制_JUC学习笔记--Atomic原子类

    Atomic 原子操作类包 Atomic包 主要是在多线程环境下,无锁的进行原子操作.核心操作是基于UnSafe类实现的CAS方法 CAS CAS: compareAndSwap :传入两个值:期望值 ...

  2. java中的CAS和原子类的实现

    什么是CAS     CAS的全称为Compare-And-Swap,直译就是对比交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,经过调查发现,其实 ...

  3. 多线程-使用大全 基础使用 / 锁 / 线程池 / 原子类 / 并发包 / CAS / AQS (2022版)

    一.多线程描述 1.什么是cpu CPU的中文名称是中央处理器,是进行逻辑运算用的主要由运算器.控制器.寄存器三部分组成, 运算器:从字面意思看就是运算就是起着运算的作用, 控制器:就是负责发出cpu ...

  4. 【JVM学习04】JMM内存模型

    文章目录 1. 原子性 1.1 原子性 1.2 问题分析 1.3 解决方法 2. 可见性 2.1 退不出的循环 2.2 解决方法 2.3 可见性 3. 有序性 3.1 诡异的结果 3.2 解决方法 3 ...

  5. Java多线程学习二十六:原子类是如何利用 CAS 保证线程安全的?

    什么是原子类,以及它有什么作用. 在编程领域里,原子性意味着"一组操作要么全都操作成功,要么全都失败,不能只操作成功其中的一部分".而 java.util.concurrent.a ...

  6. 源码学习【原子类AtomicInteger】Java原子类底层实现(解释详细)

    原子类AtomicInteger 在Java中,有很多方法可以保证多线程下数据的安全,AtomicXXXX这些类就是其中的一种,原子类,可以保证每一步操作都是原子操作.这次就对AtomicIntege ...

  7. atomic原子类实现机制_并发编程:并发操作原子类Atomic以及CAS的ABA问题

    本文基于JDK1.8 Atomic原子类 原子类是具有原子操作特征的类. 原子类存在于java.util.concurrent.atmic包下. 根据操作的数据类型,原子类可以分为以下几类. 基本类型 ...

  8. Java原子类中CAS的底层实现,java高级面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  9. 关于JCU并发包中的Atomic原子类及其CAS

    希望造成叫醒你的是梦想 而不是闹钟 目录 类型 常用方法 CAS CAS与Atomic原子类 自旋锁 CAS缺点 Atomic原子类: 在化学中,原子是构成一般物质的最小单位,是不可分割的.而在这里, ...

最新文章

  1. linux目录加了一把锁怎么办,linux 文件加锁 lockf 小结
  2. linux 安装分区设置分区大小
  3. Android之使用HTTP协议的Get/Post方式向服务器提交数据
  4. secureCRT 下载文件
  5. 2021-05-08 docker  拷贝东西到镜像,和拷贝到宿主机
  6. 新手小白零基础搭建个人博客(三)部署篇
  7. boost::static_min_max_signed_type用法的测试程序
  8. 精妙SQL语句收集(转)
  9. 拥有5大核心竞争力的华为云GaussDB,成SACC2021最靓那一个…
  10. matlab脑肿瘤识别与分割程序_车牌识别算法
  11. Centos安装php高版本
  12. w10 桌面计算机垃圾桶,解答win10我的电脑怎么放在桌面
  13. vr全景拍摄教程,怎样拍摄vr全景照片?
  14. 已解决:Connection timed out: connect. If you are behind an HTTP proxy, please configure the proxy
  15. 安装CAJViewer时遇到注册模块出现1904错误解决方法
  16. ArcBlock 分享 | 冒志鸿:我为区块链技术落地“狂”!
  17. win10系统如何清理c盘垃圾
  18. 打造数字孪生社区,极视角助力成都市成华区杉板桥社区智能感知体系建设
  19. Mycat批量插入性能测试
  20. 信息资源管理【一】之 信息资源管理基础

热门文章

  1. 甲骨文中国疯狂裁员 招聘网站上线“甲骨文人才专场”
  2. OPPO副总裁曝光Reno十倍变焦规格 能用上的安卓机皇不超过两个
  3. 网红第一股上市首日暴跌37% “为人低调”王思聪评价:公司本身有问题
  4. 中国电影史上最大泄漏事故?国家版权局出手了...
  5. 安卓非常实用的自动化测试工具 -- Monkey详细的说明
  6. OpenCV系列(一)之图像平滑
  7. linux 虚拟文件系统 源码,Linux内核源代码情状分析-虚拟文件系统
  8. 我的docker随笔19:Nextcloud部署
  9. 我的内核学习笔记1:字符设备完善
  10. 【java】Java 动态调试技术原理及实践