AtomicInteger及CAS源码解析

JDK实现锁的方式有两类:Synchronized和CAS

CAS的使用中,有直接使用的,比如AtomicInterger; 有间接使用的,比如ReentrantLock

1、CAS介绍

CAS是Compare and Swap(比较并交换)的简称

CAS有三个操作数: 内存值V, 旧的预期值A, 要修改的值B,当且仅当预期值A与内存值V相等时,则将内存值修改为B并返回true,否则返回false

2、Unfafe

JDK中sun.misc包下有一个Unsafe类,里面的方法都是native方法,这些方法提供了硬件级别的原则操作

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

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

    public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

  这些方法,在JDK内部可以直接使用(我们个人写类无法直接调用这些方法),所有的CAS操作基本都是通过Unsafe的这些compareAndSwap方法实现的。

3、AtomicInteger源码分析

源码结构如下

public class AtomicInteger extends Number implements java.io.Serializable {

    // 创建Unsave实例
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    //初始值,使用volatile类型,保证可见性
    private volatile int value;


    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    public AtomicInteger() {
    }
}

  

4、AtomicInteger的使用

AtomicInteger atomicInteger = new AtomicInteger();
 
// 设定初始值
atomicInteger.set(10);
 
// 类似于++i
int i = atomicInteger.incrementAndGet()

   

5、incrementAndGet()方法

   public final int incrementAndGet() {
	//调用unsafe.getAndAddInt方法
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

    //调用unsafe.getAndAddInt方法
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
	    // 获取当前新值,不停的获取最新值,并在当前最新值上+1
            var5 = this.getIntVolatile(var1, var2); 
         // this.compareAndSwapInt()方法也是native类型的
	 // 如果该方法返回false,也就是设置失败的情况下,则一直循环,直到设置成功
    
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

  

猜你喜欢

转载自www.cnblogs.com/linlf03/p/12636901.html
今日推荐