追赶日月的星辰 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 想用@vueuse 把项目动态改成深色主题,localStorge里面的vueuse-color-scheme一开始就给我改成了dark,不知道什么原因(相关搜索:背景颜色)
  • ¥20 OPENVPN连接问题
  • ¥15 flask实现搜索框访问数据库
  • ¥15 mrk3399刷完安卓11后投屏调试只能显示一个设备
  • ¥100 如何用js写一个游戏云存档
  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计