• 16、深入理解CAS(重点)


    引用学习(狂神说)

    什么是CAS?

    CAS:Compare and Swap,即比较再交换,直接对内存中的值进行的操作

    jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronous同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。

    我们通过AtomicInteger这个原子类的方法分析

    package com.zxh.cas;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class CASDemo {
        public static void main(String[] args) {
            // 创建整型原子类,初始化大小为2020
            AtomicInteger atomicInteger = new AtomicInteger(2020);
    
            // public final boolean compareAndSet(int expect, int update):expect期望的值,update更新的值
            // 如果期望的值是2020,那么就修改为2021,修改成功返回true,否则返回false
            System.out.println(atomicInteger.compareAndSet(2020, 2021));
    
            System.out.println(atomicInteger.compareAndSet(2020, 2022));
            System.out.println(atomicInteger.get());    // 获取内存中存放的值
        }
    }

    Unsafe 类

    分析源码

    1、发现通过unsafe调用的方法

     2、这里的Unsafe类,Java可以通过它直接操作内存

    3、我们之前使用的方法getAndIncrement对内存中的值+1操作

    • 下面分析这个方法

    private static final long valueOffset;
    
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    
    private volatile int value;
    ===========================
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
    ===========================
    public final int getAndAddInt(Object var1, long var2, int var4) {    // var2这个参数其实就是创建这个对象时,赋值的值。
        int var5;
        do {
            // getIntVolatile()获取内存中当前对象的值,经过var2偏移后的值
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
        // compareAndSwapInt方法,是再次判断var1当前对象,经过var2偏移后的值,是否等于var5的值,如果等于的话,就对当前内存中的值+var4,也就是+1。(为什么是再次呢?因为do循环中已经获取过一次)
        return var5;
    }

    CAS : 比较当前工作内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就一直循环!

     

    缺点:

    1、循环会耗时

    2、一次性只能保证一个共享变量的原子性(但是一个变量已经够了)

    3、ABA问题

    CAS:ABA问题(狸猫换太子)

     概念图理解

     代码模拟

    package com.zxh.cas;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class CASDemo {
        public static void main(String[] args) {
            // 创建整型原子类,初始化大小为2020
            AtomicInteger atomicInteger = new AtomicInteger(2020);
    
            // public final boolean compareAndSet(int expect, int update):expect期望的值,update更新的值
            // 如果期望的值是2020,那么就修改为2021,修改成功返回true,否则返回false
    //        ============ 捣乱的线程 =============
            System.out.println(atomicInteger.compareAndSet(2020, 2021));
            System.out.println(atomicInteger.compareAndSet(2021, 2020));
    
    //        ============ 正常执行的线程 =============
            System.out.println(atomicInteger.compareAndSet(2020, 2023));
            System.out.println(atomicInteger.get());    // 获取内存中存放的值
        }
    }

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    Atitit.软件GUI按钮与仪表盘(01)报警系统
    Atitit.软件仪表盘(7)温度监测子系统电脑重要部件温度与监控and警报
    Atitit.异步编程 java .net php python js 的比较
    Atitit.mssql 数据库表记录数and 表体积大小统计
    Atitit.软件仪表盘(0)软件的子系统体系说明
    Atitit. 单点登录sso 的解决方案 总结
    .atitit.web 推送实现解决方案集合(3)dwr3 Reverse Ajax
    atitit..主流 浏览器 js 引擎 内核 市场份额 attialx总结vOa9
    Atitit.软件仪表盘(4)db数据库子系统监测
    Atitit.软件仪表盘(8)os子系统资源占用监测
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13028258.html
Copyright © 2020-2023  润新知