import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;

public class CounterAtomic {
    public static void main(String[] args) throws InterruptedException {
        AtomicInteger nilai = new AtomicInteger(0);

        Runnable tugas = () -> {
            for (int i = 0; i < 100_000; i++) {
                nilai.incrementAndGet(); // atomik: baca + tambah + tulis satu kesatuan
            }
        };
        Thread a = new Thread(tugas, "teller-A");
        Thread b = new Thread(tugas, "teller-B");
        a.start();
        b.start();
        a.join();
        b.join();

        // Tiga operasi atomik lain, dijalankan thread main setelah join:
        int lama = nilai.getAndAdd(500);  // kembalikan nilai lama, lalu tambah 500
        int baru = nilai.addAndGet(10);   // tambah 10, lalu kembalikan nilai baru
        int sekarang = nilai.get();

        System.out.println("incrementAndGet 2 x 100000   : " + lama);
        System.out.println("addAndGet(10) nilai baru     : " + baru);
        System.out.println("nilai akhir                  : " + sekarang);

        // LongAdder: pecahan counter untuk kontensi sangat tinggi.
        LongAdder jumlah = new LongAdder();
        Runnable tugasAdder = () -> {
            for (int i = 0; i < 100_000; i++) {
                jumlah.increment();
            }
        };
        Thread c = new Thread(tugasAdder, "teller-C");
        Thread d = new Thread(tugasAdder, "teller-D");
        c.start();
        d.start();
        c.join();
        d.join();
        System.out.println("LongAdder sum() 2 x 100000   : " + jumlah.sum());
    }
}
