美文网首页
Java CAS简单说明

Java CAS简单说明

作者: 听歌闭麦开始自闭 | 来源:发表于2019-04-26 11:39 被阅读0次

如果懂JMM,这个压根就不用看。

CAS(Compare And Swap)

其保留有3个值 V(内存值)A(旧的预期值/旧值)B(要修改的值/新值)
V指的是主存中的存在的值;A指的是每个线程自己持有的V的副本;B是经过一系列自己指定的运算后的结果。
当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做并返回false

设定:
1.内存中有个空间(Q)存储了一个值为1,我们使用多线程且使用CAS进行修改会发生如下反应。
2.有2个线程(A和B)同时对Q进行 +1 操作。(可以参考JDK 1.7中AtomicInteger)

// JDK 1.7 中的代码示例

private volatile int value;
private static final Unsafe unsafe = Unsafe.getUnsafe();

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

public final int get() {
    return value;
}

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
根据JMM可以得知,2个线程会各自获取一份Q的副本(值为1)。
1.线程A开始运行,current获取到线程中的副本值为1,然后执行完成+1操作,此时线程切换给B操作。
2.线程B开始运行,current获取到线程中的副本值为1,然后执行完成+1操作,`之后拿着线程B中Q的副本[current]与Q的值进行比较,如果两值相等就将计算出来的next进行替换掉Q的原值(CAS操作)`,此时线程切换给A操作。
3.线程A开始运行,拿着线程A中Q的副本进行相同的比较与赋值操作(CAS操作),在V与A的比较中发现不对等(**内存中的Q值为2,线程B的副本值为1**),于是认为value正在被另外一个线程操作,所以不能进行值替换。**
4.这个时候线程A会再一次取Q中的值作为新的副本,再次进行+1操作并通过CAS尝试写入新值,如果一直写不进去这个过程会不断重复,直到能成功的执行为止。

根据代码可以看出这个valuevolatile修饰符十分重要,当操作失败后能及时的获取到其他线程对其的修改值。
如果去掉volatile修饰符,那不同线程之间就完全感知不到对方对值的修改,也就是说在第4步的时候,线程A永远取不到Q的新值。

至于compareAndSet方法,我们也能从示例代码中清楚的看到是调用了Unsafe这个类中的方法。
Unsafe提供了硬件级别的原子操作,但不建议自己使用。

CAS的ABA问题

在上诉基础上,多添加几个线程进行对Q的操作,要求是加减都有。
那线程中CAS操作会不会存在问题?
线程L的副本存储的为1,我们不能确保在线程L中进行V和A的比较操作之前,是否有其他线程将Q的值改为2后又改回了1。
这就是ABA问题,当然可以采用版本号等方式解决。

ABA问题的例子:
主存中的V的值为1。
线程A中副本值为1,然后进行+1操作,线程切换。
线程B中的副本之为1,然后进行+1操作,最后通过CAS对V的值进行写入,现在V的值为2,线程切换。
线程C中的副本之为2,然后进行-1操作,最后通过CAS对V的值进行写入,现在V的值为1,线程切换。
线程A之前已经计算完了,现在尝试进行用CAS操作,发现V和自己的副本值相同后进行写入操作。

虽然看起来没什么问题,但可能在某些逻辑中就会导致潜在问题的出现。

额外补充

观看其他的java.util.concurrent中的代码不难发现,该包是基于CAS的构建的,而CAS又依赖于Unsafe类。

相关文章

  • Java CAS简单说明

    如果懂JMM,这个压根就不用看。 CAS(Compare And Swap) 其保留有3个值 V(内存值)、A(旧...

  • shiro-cas +spring实现sso单点登录

    title: shiro-cas 单点登录爬过的坑notebook: 笔记tags:java cas简单服务端-客...

  • (11)CAS

    什么是CAS 简单的说,CAS就是compare and swap,翻译成中文就是比较与交换.在java多线程中,...

  • Java - CAS用法及说明

    CAS即compare and swap,表示比较并交换,在java中依赖Unsafe类来实现,常见的CAS实现有...

  • CAS ABA问题

    java.util.concurrent包的最底层基础CAS技术,原理很简单。 CAS有3个操作数,内存值V,旧的...

  • Java中的CAS

    ​ Java中的CAS CAS全称 Compare A...

  • JAVA CAS底层实现

    JAVA CAS Java CAS底层都是调用了Unsafe类的compareAndSwap方法都是native的...

  • 最简单的CAS机制说明

    CAS(Compare-And-Swap) 算法保证数据变量的原子性 CAS 算法是硬件对于并发操作的支持 CAS...

  • Java Concurrent CAS使用&原理

    前言 CAS 可以简单描述比较并交换,Java中轻量级锁的理论支持。CAS很早就出现了,并且以此为理论基础实现了很...

  • Java多线程之CAS原理和原子操作

    1 CAS 1.1 CAS应用分析 CAS:Compare and Swap, 翻译成比较并交换。java.uti...

网友评论

      本文标题:Java CAS简单说明

      本文链接:https://www.haomeiwen.com/subject/tikfnqtx.html