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