追赶日月的星辰 2021-11-05 09:26 采纳率: 100%
浏览 20
已结题

【Java】LongAdder一定比AtomicLong性能要高吗

问题:
代码是《Java虚拟机-JVM故障诊断与性能优化》的,分别使用Synchronized/AtomicLong/LongAdder实现累加到TARGET_COUNT,但是最后发现无论线程数多少,LongAdder的性能都是最低的。

环境:
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

package com.example.demo.atomic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.IntStream;

public class AtomicLess {

    private static final int MAX_THREAD_SIZE = 3;
    private static final int MAX_TASK_SIZE = 3;
    private static final int TARGET_COUNT = 10000000;

    private AtomicLong account = new AtomicLong(0L);
    private long count = 0;
    private LongAdder longAdder = new LongAdder();

    static CountDownLatch cdlsync = new CountDownLatch(MAX_TASK_SIZE);
    static CountDownLatch cdlatomic = new CountDownLatch(MAX_TASK_SIZE);
    static CountDownLatch cdllad = new CountDownLatch(MAX_TASK_SIZE);

    protected synchronized long inc(){
        return ++count;
    }

    protected synchronized long getCount(){
        return count;
    }

    protected void clear(){
        this.count = 0;
    }

    public class SyncThread implements Runnable{

        long startTime;
        AtomicLess out;

        public SyncThread(AtomicLess out,long startTime){
            this.out = out;
            this.startTime = startTime;
        }

        @Override
        public void run() {
            long v = out.getCount();
            while (v<TARGET_COUNT){
                v = out.inc();
            }
            long endTime = System.currentTimeMillis();
            System.out.println("SyncThread Spend "+(endTime-startTime)+"ms v="+v);
            cdlsync.countDown();
        }
    }

    public class AtomicThread implements Runnable{
        long startTime;

        public AtomicThread(long startTime){
            this.startTime = startTime;
        }

        @Override
        public void run() {
            long v = account.get();
            while (v < TARGET_COUNT){
                v = account.incrementAndGet();
            }

            long endTime = System.currentTimeMillis();
            System.out.println("AtomicThread Spend "+(endTime-startTime)+"ms v="+v);
            cdlatomic.countDown();
        }
    }

    public class LongAdderThread implements Runnable{
        long startTime;

        public LongAdderThread(long startTime){
            this.startTime = startTime;
        }

        @Override
        public void run() {
            long v = longAdder.sum();
            while (v < TARGET_COUNT){
                longAdder.increment();
                v = longAdder.sum();
            }

            long endTime = System.currentTimeMillis();
            System.out.println("LongAdderThread spend "+(endTime-startTime)+"ms v="+v);
            cdllad.countDown();
        }
    }

    private void start(Runnable runnable,CountDownLatch cdl) throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(MAX_THREAD_SIZE);
        IntStream.range(0,MAX_TASK_SIZE).forEach(i ->service.execute(runnable));
        cdl.await();
        service.shutdown();
    }

    /**
     * 验证使用Synchronized锁执行效率
     * 使用Executors开启{@value MAX_THREAD_SIZE}个线程
     * 循环{@value MAX_TASK_SIZE}次提交任务
     * 开启CountLatchDown等待所有任务执行完成
     * @throws InterruptedException
     */
    public void startSync() throws InterruptedException {
        start(new SyncThread(this,System.currentTimeMillis()),cdlsync);
    }

    /**
     * 验证CAS执行效率
     * @throws InterruptedException
     */
    public void startAtomic() throws InterruptedException {
        start(new AtomicThread(System.currentTimeMillis()),cdlatomic);
    }

    /**
     * 验证LongAdder的执行效率
     * @throws InterruptedException
     */
    public void startLongAdder() throws InterruptedException {
        start(new LongAdderThread(System.currentTimeMillis()),cdllad);
    }

    public static void main(String[] args) throws InterruptedException {
        AtomicLess atomicLess = new AtomicLess();
        atomicLess.startLongAdder();
        atomicLess.startSync();
        atomicLess.startAtomic();

    }

}


img

  • 写回答

1条回答 默认 最新

报告相同问题?

问题事件

  • 系统已结题 11月16日
  • 已采纳回答 11月8日
  • 创建了问题 11月5日

悬赏问题

  • ¥15 用python如何确定子元素在父元素中的位置
  • ¥15 obj文件滤除异常高程
  • ¥15 用mathematicas或者matlab计算三重积分
  • ¥15 Loop unrolling的runtime计算
  • ¥100 NVMe-oF的Target端,开启attr_offload后,测试失败。
  • ¥100 有偿照片马赛克去掉,保留原始数据
  • ¥15 c# winform http报错,如何解决?
  • ¥15 统计软件及应用-r软件
  • ¥15 爬虫返回的js数据结构如何处理
  • ¥15 python初学者中间insert部分不知道怎么写,请教各位中间如何填写。还想问问大家0基础如何入手python和c语言,期待各位的回复和帮助。