2-2CAS(并发面试版)

1 什么是CAS?

比较并交换
如果线程的期望值和物理内存的真实值一致,就修改
如果线程的期望值和物理内存的真实值不一致,本次修改失败,需要重新获取主物理内存的真实值。

public class CASDemo {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(666);
        // 获取真实值,并替换为相应的值
        boolean b = atomicInteger.compareAndSet(666, 2019);
        System.out.println(b); // true
        boolean b1 = atomicInteger.compareAndSet(666, 2020);
        System.out.println(b1); // false



        //getAndIncrement 解决了多线程问题
        atomicInteger.getAndIncrement();
    }
}

在这里插入图片描述
1 new了一个对象,初始值是5 。存在主物理内存中。
2 t1 ,t2分别从主内存中拷贝到自己的工作内存中。
3 t1 改为2019 ,快照值和主主内存的值都是5,允许写回主内存并交换
4 t2 改为1020 ,但此时快照的值5 和主内存的值2019不一致,本次修改失败

总结:
CAS:
如果线程的期望值和物理内存的真实值一致,就修改
如果线程的期望值和物理内存的真实值不一致,本次修改失败,需要重新获取主物理内存的真实值。

2 CAS 底层原理?谈谈对 UnSafe 的理解?

2.1getAndIncrement();

/**
 * Atomically increments by one the current value.
 *
 * @return the previous value
 */
public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

2.2 UnSafe 类

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            // 获取下面 value 的地址偏移量
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;
	// ...
}

在这里插入图片描述

2.3CAS 是什么

。CAS 的全称 Compare-And-Swap,它是一条 CPU 并发。

。它的功能是判断内存某一个位置的值是否为预期,如果是则更改这个值,这个过程就是原子的。

。CAS 并发原体现在 JAVA 语言中就是 sun.misc.Unsafe 类中的各个方法。调用 UnSafe 类中的 CAS 方法,JVM 会帮我们实现出 CAS 汇编指令。这是一种完全依赖硬件的功能,通过它实现了原子操作。由于 CAS 是一种系统源语,源语属于操作系统用语范畴,是由若干条指令组成,用于完成某一个功能的过程,并且原语的执行必须是连续的,在执行的过程中不允许被中断,也就是说 CAS 是一条原子指令,不会造成所谓的数据不一致的问题。
在这里插入图片描述

2.4 CAS 的缺点?

。循环时间长开销很大
如果 CAS 失败,会一直尝试,如果 CAS 长时间一直不成功,可能会给 CPU 带来很 大的开销(比如线程数很多,每次比较都是失败,就会一直循环),所以希望是线程数比较小的场景。
。只能保证一个共享变量的原子操作
。对于多个共享变量操作时,循环 CAS 就无法保证操作的原子性。
。引出 ABA 问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值