16深入理解CAS(重点)

Posted zxhbk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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());    // 获取内存中存放的值
    }
}

技术图片

 

以上是关于16深入理解CAS(重点)的主要内容,如果未能解决你的问题,请参考以下文章

深入理解CAS

并发编程之深入理解CAS

深入理解CAS (自旋锁)

JUC并发编程(11)--- 深入理解CAS

深入理解JVM之CAS原子操作

深入理解CAS