追赶日月的星辰 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 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线