package org.example;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;


public class Main2 {
    public static void main(String[] args) {
        for (int i = 0; i < 6; i++) {
            demo(
                    ()->new AtomicLong(0),
                    (adder)->{
                        adder.getAndIncrement();
                    }
            );
        }
        System.out.println("----------------");
        for (int i = 0; i < 6; i++) {
            demo(
                    ()->new LongAdder(),
                    longAdder -> {
                        longAdder.increment();
                    }
            );
        }
    }
    private static <T> void demo(Supplier<T> adderSupplier, Consumer<T> action) {
        T adder = adderSupplier.get();
        List<Thread> ts = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            ts.add(new Thread(()->{
                for (int j = 0; j < 20000000; j++) {
                    action.accept(adder);
                }
            }));
        }
        long start = System.currentTimeMillis();
        ts.forEach(Thread::start);
        ts.forEach(thread -> {
            try {
                thread.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        long end =  System.currentTimeMillis();
        System.out.println(adder + " cost: " + (end - start) + " ms");
    }
}