CAS

本文介绍CAS、通过案例去演示CAS、CAS的应用场景、如何利用CAS进行原子操作、CAS的缺点。

概述

  CAS是一种思想,使用并发场景,是一种原子性的操作,实现不能被其他线程打断的情况。

  思路:我认为他应该是A,如果是我就修改,如果不是我就放弃他,可以避免多人修改引发的问题。

  具体参数:内存值、预期值、修改值,只有当内存值和预期值相等的时候,才会去修改;利用CPU的指令保证他的原子性。

代码示例

  两个线程都去修改公共变量,只有一个可以修改成功,示例代码如下所示。

  

package com.yang.cas;

import javax.management.relation.RoleUnresolved;

/**
 * 模拟CAS操作
 */
public class SimulatedCASDemo implements Runnable {
    private volatile int value;

    public synchronized int compareAndSwap(int expectedValue, int newValue) {
        int oldValue = value;
        if (oldValue == expectedValue) {
            value = newValue;
        }
        return value;
    }

    @Override
    public void run() {
        compareAndSwap(0, 1);
    }

    /**
     * 两个线程都去修改参数,只有个线程可以修改成功
     * 最终的输出结果为1
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        SimulatedCASDemo simulatedCASDemo=new SimulatedCASDemo();
        Thread thread1=new Thread(simulatedCASDemo);
        Thread thread2=new Thread(simulatedCASDemo);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(simulatedCASDemo.value);
    }
}

应用场景

   乐观锁 

  并发容器:concurrentHashMap

  原子类

 

原子类如何实现CAS

  原子类AtomicInteger加载unsafe工具,用来直接操作内存数据;用volatile 修饰value字段,保证可见性。

  Unsafe可以拿到内存地址,部分代码如下所示:

  

static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;



.........................
public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }

 CAS缺点

  1.ABA问题:先修改为A,再修改为B,再修改为A,检查和我的值是否相等,乐观锁可以加个版本号

  2.自旋时间较长

posted @ 2020-04-23 16:30  cnxieyang  阅读(162)  评论(0编辑  收藏  举报
联系邮箱:cnxieyang@163.com