原子累加器
文章目录
1.LongAdder比AtomicLong性能好的原因
性能提升的原因很简单,就是在有竞争时,设置多个累加单元,Therad-0 累加 Cell[0],而 Thread-1 累加Cell[1]… 最后将结果汇总。这样它们在累加时操作的不同的 Cell 变量,因此减少了 CAS 重试失败,从而提高性能。
2.AtomicLong与LongAdder的比较代码
package com.concurrent.p7;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;
@Slf4j(topic = "c.Test_AtomicLong_LongAdder")
public class Test_AtomicLong_LongAdder {
/**
* @param supplier ()->(结果)
* @param consumer (参数)->()
* @param <T>
*/
public static <T> void demo(Supplier<T> supplier, Consumer<T> consumer) {
T adder = supplier.get(); //累加器,初始值=0
List<Thread> threadList = new ArrayList<>();
//添加计时器
long start = System.currentTimeMillis();
//创建4个线程,每个线程累加500000次
for (int i = 0; i < 4; i++) {
threadList.add(new Thread(() -> {
for (int j = 0; j < 500000; j++) {
consumer.accept(adder);
}
}));
}
//启动每个线程
threadList.forEach(t -> {
t.start();
});
//等待每个线程执行结束
threadList.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//查看累加器
log.debug(adder.toString() + ",耗时:" + (System.currentTimeMillis() - start));
}
//测试AtomicLong累加效率
@Test
public void test_AtomicLong() {
//10:27:11.592 [main] DEBUG c.Test_AtomicLong_LongAdder - 2000000,耗时:33
demo(
() -> new AtomicLong(0),
(addr) -> {
addr.getAndIncrement();
}
);
}
//测试LongAdder