简体   繁体   中英

How To Use LongAdder On Multithreaded

Currently Studying java and i stumbled on LongAdder which was pointed to be faster than AtomicLong so i've been trying to make it work but the last value is always 1 execution more

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

My understanding is a bit low but i'm wondering is there an approach using LongAdder that can work and still remain fast as i was told AtomicLong with alot of threads is slow compared to LongAdder

You have a race condition; there is a non atomic check then modify. You increment the value after you check if it hasn't reached the maximum value. This isn't atomic, so multiple threads could do this at the same time. If you want something atomic, have a look at the AtomicLong/AtomicInteger.

The LongAdder is useful if you want to have a cheap progress counter whereby multiple threads can update the counter (at a very high rate) and once and a while you will read out the value. Sum could be very expensive because it needs to iterate over every counter inside the LongAdder and for each counter, it could acquire access to a cacheline that is probably not in the right state at the calling core. And this leads to a lot of cache coherence traffic and potentially memory traffic (eg when the dirty cacheline is written to main memory as would happen on MESI based systems).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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