其他分享
首页 > 其他分享> > 02-JUC-CAS

02-JUC-CAS

作者:互联网

CAS

JUC中多数类是通过volatile和CAS来实现的,CAS本质上提供的是一种无锁方案,而Synchronized和Lock是互斥锁方案; java原子类本质上使用的是CAS,而CAS底层是通过Unsafe类实现的。

线程安全的方法有:

第一种方法是通过锁的方式来实现线程安全,CAS是通过无锁的方式实现的,下面重点说说CAS是如何实现线程安全的

什么是CAS

就是有一个原值A, 如果要更新为值B,在更新前先比较原值A有没有发生变化,如果没有发生变化,就将A更新为值B,如果发生了变化就不交换

用AtomicInteger 举个小栗子:多线程情况下新增一个值

AtomicInteger a  =  new AtomicInteger(0);
public int add(){
	return a.addAndGet(1);
}

CAS 有什么问题

synchronized是通过锁来保证线程安全的,是一种悲观锁策略

而CAS是一种乐观锁策略,但是在并发问题上性能更佳,它可能会出现的问题

Unsafe类

我们上面提过,很多原子类是通过Unsafe实现的,

可以看一眼Unsafe类

public final class Unsafe {
	...// 省略
  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 long getAndAddLong(Object var1, long var2, long var4) {
        long var6;
        do {
            var6 = this.getLongVolatile(var1, var2);
        } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

        return var6;
    }

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

        return var5;
    }

    public final long getAndSetLong(Object var1, long var2, long var4) {
        long var6;
        do {
            var6 = this.getLongVolatile(var1, var2);
        } while(!this.compareAndSwapLong(var1, var2, var6, var4));

        return var6;
    }

    public final Object getAndSetObject(Object var1, long var2, Object var4) {
        Object var5;
        do {
            var5 = this.getObjectVolatile(var1, var2);
        } while(!this.compareAndSwapObject(var1, var2, var5, var4));

        return var5;
    }
    ...//省略
}

可以发现,它是通过while自旋compareAndSwap进行CAS更新(如果失败就一直自旋)。里面的compareAndSwap* 都是底层的native方法

下面是Unsafe可以实现的功能(取自网络图)

比如,AtomicInteger就是通过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 {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    // volatile  值
    private volatile int value;

    /**
     * Creates a new AtomicInteger with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }
    ...//省略
   public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }

 
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
    ...//省略
}

可以看到,value用了volatile来修饰,保证了线程的可见性,同时使用CAS来保证更新时的原子性

标签:02,JUC,var1,var2,CAS,int,var5,public
来源: https://www.cnblogs.com/volsnow/p/15767040.html