import java.util.concurrent.atomic.AtomicInteger;

public class ContohUjiKonkuren {

    // ---- strategi 1: logika agregasi murni, diuji seperti biasa ----

    static long hitungTotal(long[] kontribusi) {
        long total = 0;
        for (long nilai : kontribusi) {
            total += nilai;
        }
        return total;
    }

    // ---- kode paralel yang diuji: penghitung atomik ----

    static final class Penghitung {

        private final AtomicInteger nilai = new AtomicInteger();

        void tambah(int berapa) {
            for (int i = 0; i < berapa; i++) {
                nilai.incrementAndGet();
            }
        }

        int nilai() {
            return nilai.get();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // uji 1: bagian murni diuji deterministik tanpa thread
        long[] contoh = {1000, 1000, 1000, 1000};
        System.out.println("uji logika murni : total = " + hitungTotal(contoh));

        // uji 2: stress test terbatas dengan join ber-timeout
        int jumlahPekerja = 4;
        int tambahanPerPekerja = 1000;

        Penghitung penghitung = new Penghitung();
        Thread[] pekerja = new Thread[jumlahPekerja];
        long[] kontribusi = new long[jumlahPekerja];

        for (int t = 0; t < jumlahPekerja; t++) {
            final int indeks = t;
            pekerja[t] = new Thread(() -> {
                penghitung.tambah(tambahanPerPekerja);
                kontribusi[indeks] = tambahanPerPekerja;
            });
            pekerja[t].start();
        }

        for (Thread t : pekerja) {
            t.join(5_000); // batas atas: suite tidak menggantung tanpa akhir
            if (t.isAlive()) {
                throw new AssertionError("pekerja tidak selesai dalam batas waktu");
            }
        }

        // seluruh pekerja sudah bergabung: aman membaca hasil bersama
        int hasil = penghitung.nilai();
        System.out.println("uji paralel      : hasil = " + hasil);
        System.out.println("total kontribusi : " + hitungTotal(kontribusi));
        System.out.println("konsisten        : " + (hasil == hitungTotal(kontribusi)));
    }
}
