CAS的介绍

  是乐观锁和原子类的底层原理

1.大纲

  什么是cas

  代码演示

  应用场景

  

一:CAS

1.说明

  CAS:Compare and Swap,即比较再交换。

  jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。

  https://www.cnblogs.com/juncaoit/p/12386737.html

2.cpu的特殊指令

  cpu保证原子性

package com.jun.juc.cas;

/**
 * CAS等价代码
 */
public class SimulatedCas {
    private volatile int value;

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

  

二:代码演示

1.演示

package com.jun.juc.cas;

import java.util.concurrent.Executors;

/**
 * CAS演示
 */
public class Competition implements Runnable{
    private volatile int value;

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

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

    public static void main(String[] args) throws Exception{
        Competition competition = new Competition();
        competition.value = 0;
        Thread t1 = new Thread(competition);
        Thread t2 = new Thread(competition);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(competition.value);
    }
}

  效果:

Connected to the target VM, address: '127.0.0.1:62710', transport: 'socket'
1
Disconnected from the target VM, address: '127.0.0.1:62710', transport: 'socket'

Process finished with exit code 0

  

三:应用场景

1.举例

  乐观锁

  并发容器

  原子类

2.并发容器

  ConcurrentHashmap

四:原子类什么应用CAS的

1.说明

  AtomicInteger架在Unsafe工具,用来直接操作内存数据

  用Unsafe来实现底层操作

  用volatile修饰value字段,保证可见性

  getAndAddInt方法分析

2.代码

 // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    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;

  

    /**
     * Atomically adds the given value to the current value.
     *
     * @param delta the value to add
     * @return the previous value
     */
    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }

  

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;
    }

  

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

  

3.Unsafe类

  是CAS核心类

  java无法直接访问底层操作系统,是通过本地native方法来进行访问。jvm还是提供了一个后门,这个类提供了硬件级别的原子操作

  valueOff表示的是变量值在内存中的偏移地址,因为unsafe就是根据内存偏移地址获取数据的原值的,这样我们就可以通过unsafe实现cas了

  

五:不好的问题

1.ABA问题

  解决的方式,类似数据库那种,添加版本号

2.自旋问题长

  

原文地址:https://www.cnblogs.com/juncaoit/p/13062995.html