Java并发编程CAS类的使用

Java多线程累加,是并发编程的入门代码,一般是通过Synchronized同步方法来保证多线程累加结果的正确性。在Java中,还可以通过CAS方法来进行多线程累加来确保结果的正确性。

CAS不同于同步锁,这是一种无锁模式,通过硬件来实现的对比交换,核心逻辑就是保证一组执行不会中断、拆分的执行,这就是我们常说的原子性,CAS的原子性是通过硬件来保证的。

Java中已经提供了相关的原子类,如下:

基本数据类型:
AtomicBoolean
AtomicInteger
AtomicLong

数组:
AtomicIntegerArray
AtomicLongArray
AtomicRefererenceArray

累加器:
DoubleAccumulator
DoubleAdder
LongAccumulator
LongAdder

引用类型:
AtomicReference
AtomicStampedReference
AtomicMarkableReference

对象属性更新器:
AtomicIntegerFieldUpdater
AtomicLongFieldUpdater
AtomicReferenceFieldUpdater

我们来演示一个例子。

先来看一个原子整型类的例子。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Auther: www.itzhimei.com
 * @Description:
 */
public class AtomicTest {

    private static final AtomicInteger ai = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch cdl = new CountDownLatch(1);
        CountDownLatch cdl2 = new CountDownLatch(1000);
        for(int i=0; i<1000; i++) {
            new Thread(()-> {
                try {
                    cdl.await();
                    ai.incrementAndGet();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    cdl2.countDown();
                }
            }).start();

        }
        cdl.countDown();
        cdl2.await();
        System.out.println(ai);
    }
}

输出:

1000

再来看一个原子引用类型的例子。

public class AtomicTest {

    private static final AtomicIntegerFieldUpdater aifu = AtomicIntegerFieldUpdater.newUpdater(ScoreClass.class,"score");
    private static final AtomicInteger ai = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        ScoreClass sc = new ScoreClass();
        CountDownLatch cdl = new CountDownLatch(1000);
        for(int i=0; i<1000; i++) {
            new Thread(()->{
                aifu.incrementAndGet(sc);
                ai.incrementAndGet();
                cdl.countDown();
            }).start();
        }
        cdl.await();
        System.out.println(aifu.get(sc));
        System.out.println(ai.get());

    }

    static class ScoreClass {
        volatile int score = 0;
    }

}

输出:

1000
1000