平时开发,如果做计数器或者并发限制等需求,我们一般想到的是Atomic系列(如AtomicInteger)。一般并发场景下,使用Atomic其实是问题不大,但如果是并发量非常恐怖,LongAdder爆发的威力是非常强大的。
win10,处理器-Intel(R) Core(TM) i7-8550U,内核-4,逻辑处理器-6
主要对1 5 10 20亿分别进行计数。测试思路是将N个任务丢到线程池,由线程池中的线程再各自循环M次进行计数操作,最终达到N*M=10亿。主要代码如下:
public class LongAdderTest {
// private static AtomicLong counter = new AtomicLong();
private static LongAdder counter = new LongAdder();
private static ExecutorService executorService = Executors.newFixedThreadPool(7);
public static void main(String[] args) {
LongAdderTest longAdderTest = new LongAdderTest();
long l = System.currentTimeMillis();
//开启N个任务并且每个任务循环M次,最总计数到 sum(N*M) 所花费的时间
for (int i = 1; i <= 100000; i++) {
executorService.execute(()->{
for (int j = 1;j<=5000;j++){
longAdderTest.add();
}
});
}
executorService.shutdown();
while (true){
//等待全部线程执行完
if (executorService.isTerminated()){
break;
}
}
// System.out.println("result is "+counter.get()+" and spend time: "+(System.currentTimeMillis()-l)/1000 + "(s)");
System.out.println("result is "+counter.sum()+" and spend time: "+(System.currentTimeMillis()-l)/1000 + "(s)");
}
private void add(){
// counter.addAndGet(1);
counter.add(1L);
}
}
some | 1亿 | 5亿 | 10亿 | 20亿 |
---|---|---|---|---|
AtomicLong | 2s | 9s | 21s | 36s |
LongAdder | 0s | 1s | 1s | 3s |
可以看出,当超过1一个亿时,他们的差距开始拉开了。说一下,以上数据仅是本人电脑环境测出来的,不同环境可能结果有些差异。
LongAdder高性能主要还是引入了数组对并发更新的负载,说白了,就是分摊出来计算。到这里,你可以想想ConcurrentHashMap怎么实现高并发下的元素计数了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。