码迷,mamicode.com
首页 > 其他好文 > 详细

16、深入理解CAS(重点)

时间:2020-06-02 00:04:06      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:技术   bsp   lib   bool   private   模拟   upd   ctf   重点   

引用学习(狂神说)

什么是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(重点)

标签:技术   bsp   lib   bool   private   模拟   upd   ctf   重点   

原文地址:https://www.cnblogs.com/zxhbk/p/13028258.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!