Java_CAS详解


一、什么是CAS

CAS: Compare and Swap,翻译成比较并交换。是解决多线程并行情况下使用锁造成性能损耗的一种机制。执行函数CAS(V, E, N)

实现思想:CAS有3个操作数,内存值V,旧的预期值E,要修改的新值N。当且仅有预期值E和内存值V相同时,将内存值V修改为N。否则说明已经被其他线程更新,处理器不做任何操作。

二、CAS应用之原子类(Atomic类)

java.util.concurrent包中的Atomic 原子类

JUC并发包中Atomic原子类存放位置
在这里插入图片描述

1.原子更新基本类型类 cas

AtomicBoolean: 原子更新布尔类型。
AtomicInteger: 原子更新整型。
AtomicLong: 原子更新长整型。

2.原子更新数组

AtomicIntegerArray: 原子更新整型数组里的元素。
AtomicLongArray: 原子更新长整型数组里的元素。
AtomicReferenceArray: 原子更新引用类型数组里的元素。

3.原子更新引用类型

AtomicReference: 原子更新引用类型。
AtomicReferenceFieldUpdater: 原子更新引用类型的字段。
AtomicMarkableReferce: 原子更新带有标记位的引用类型,可以使用构造方法更新一个布尔类型的标记位和引用类型。

4.原子更新字段类

AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器。
AtomicLongFieldUpdater: 原子更新长整型字段的更新器。
AtomicStampedFieldUpdater: 原子更新带有版本号的引用类型。

Unsafe类

  • Unsafe类,全限定名是sun.misc.Unsafe,从名字中我们可以看出来这个类对普通程序员来说是“危险”的,一般应用开发者不会用到这个类。
  • Unsafe底层是基于CAS实现的。
  • Unsafe类是"final"的,不允许继承。且构造函数是private的。
  • Atomic类中调用Unsafe方法保证多线程数据的正确性。

三、AtomicInteger类

AtomicInteger类保证多线程数据安全。

public class Thread01 implements Runnable {
    private static Integer sum = 0;
    private static AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public void run() {
        cal();
    }

    private void cal() {
        for (int i = 0; i < 10000; i++) {
            sum++;
            //原子类和lock锁底层都是cas实现的
            atomicInteger.incrementAndGet();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread01 threadCount = new Thread01();
        Thread thread1 = new Thread(threadCount);
        Thread thread2 = new Thread(threadCount);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(sum);//11979
        System.out.println(atomicInteger.get());//20000
    }
}

AtomicInteger底层基于CAS实现

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

    private volatile int value;
    
	//拿到当前的数值
    public final int get() {
        return value;
    }
    
......

	//数值加1
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
	//数值减1
    public final int decrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
    }
    
......
}

四、CAS优缺点

优点:

  • 避免用户态到内核态切换

缺点:

  • 非常消耗cpu的资源
  • 会出现ABA问题,可以通过添加版本号解决

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值