繁体   English   中英

如何在多线程上使用 LongAdder

[英]How To Use LongAdder On Multithreaded

目前正在研究 java,我偶然发现了 LongAdder,它被指出比 AtomicLong 快,所以我一直在努力让它工作,但最后一个值总是多执行 1 次

import java.util.concurrent.atomic.LongAdder;

public class Main {
    public static LongAdder counter = new LongAdder();
    public static int Target = 100;
    public static void main(String[] args) {
        System.out.println("Starting Program");

        for (int i=0;i<5;i++){
            new Thread(Main::run).start();
        }
        new Thread(() -> {
            updateprint();
        }).start();
        System.out.println(counter);
    }

    private static void run(){
        try {
            while (counter.intValue()<Target){
                Thread.sleep(1000);
                counter.increment();
                counter.sum();
            }
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    private static void updateprint() {
        try {
            while (counter.intValue()<=Target ){
                Thread.sleep(1500);
                System.out.println("Updated Current Number :"+counter.intValue());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Output

0
Updated Current Number :5
Updated Current Number :15
Updated Current Number :20
Updated Current Number :26
Updated Current Number :35
Updated Current Number :40
Updated Current Number :50
Updated Current Number :55
Updated Current Number :65
Updated Current Number :75
Updated Current Number :80
Updated Current Number :85
Updated Current Number :95
Updated Current Number :100
Updated Current Number :104

Process finished with exit code 0

我的理解有点低,但我想知道是否有一种使用 LongAdder 的方法可以工作并且仍然保持快速,因为我被告知 AtomicLong 与 LongAdder 相比,有很多线程慢

你有一个竞争条件; 有一个非原子检查然后修改。 在检查它是否未达到最大值后增加该值。 这不是原子的,因此多个线程可以同时执行此操作。 如果你想要一些原子的东西,看看 AtomicLong/AtomicInteger。

如果您想要一个便宜的进度计数器,LongAdder 很有用,多个线程可以更新计数器(以非常高的速率)并且偶尔您会读出该值。 Sum 可能非常昂贵,因为它需要遍历 LongAdder 内的每个计数器,并且对于每个计数器,它可以获得对可能不在调用核心的正确 state 中的缓存行的访问。 这会导致大量缓存一致性流量和潜在的 memory 流量(例如,当脏缓存行写入主 memory 时,就像在基于 MESI 的系统上发生的那样)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM