平时开发,如果做计数器或者并发限制等需求,我们一般想到的是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 删除。