zoukankan      html  css  js  c++  java
  • 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());    // 获取内存中存放的值
        }
    }

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    js图片飘动
    实战ASP.NET大规模网站架构:Web加速器(1)【转】
    DNS服务器设置详解
    Lucene:基于Java的全文检索引擎简介【转】
    传道解惑 软件开发技术名词解密(转载)
    UTF8 and Unicode FAQ
    高并发 高负载 网站系统架构 !深入讨论!【转载】
    (转)值的关注的Java开源项目
    MSDN:Webcast 系列课程
    ASP.NET MVC 学习网站
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13028258.html
Copyright © 2011-2022 走看看