import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class CacheBacaTulis {
    private static class CacheProduk {
        // HashMap biasa: aman karena SELURUH aksesnya dijaga ReadWriteLock.
        private final Map<String, Integer> data = new HashMap<>();
        private final ReentrantReadWriteLock kunci = new ReentrantReadWriteLock();

        void simpan(String kode, int harga) {
            kunci.writeLock().lock();
            try {
                data.put(kode, harga);
            } finally {
                kunci.writeLock().unlock();
            }
        }

        Integer baca(String kode) {
            kunci.readLock().lock();
            try {
                return data.get(kode);
            } finally {
                kunci.readLock().unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        CacheProduk cache = new CacheProduk();

        // Fase tulis: satu penulis mengisi tiga produk lebih dulu.
        Thread penulis = new Thread(() -> {
            cache.simpan("P-001", 15000);
            cache.simpan("P-002", 27500);
            cache.simpan("P-003", 9900);
        }, "penulis");
        penulis.start();
        penulis.join();

        // Fase baca: tiga pembaca membaca ketiga produk secara bersamaan.
        String[] daftarKode = {"P-001", "P-002", "P-003"};
        int[] total = new int[3];
        Thread[] pembaca = new Thread[3];
        for (int i = 0; i < pembaca.length; i++) {
            int indeks = i;
            pembaca[i] = new Thread(() -> {
                int jumlah = 0;
                for (String kode : daftarKode) {
                    Integer harga = cache.baca(kode);
                    if (harga != null) {
                        jumlah += harga;
                    }
                }
                total[indeks] = jumlah; // kumpulkan hasil, cetak setelah join
            }, "pembaca-" + (i + 1));
            pembaca[i].start();
        }
        for (Thread t : pembaca) {
            t.join();
        }

        // Pembaruan harga dilakukan setelah seluruh pembaca selesai.
        cache.simpan("P-003", 12500);

        System.out.println("total harga yang dibaca tiap pembaca:");
        for (int i = 0; i < total.length; i++) {
            System.out.println("  pembaca-" + (i + 1) + ": " + total[i]);
        }
        System.out.println("harga P-003 setelah pembaruan: " + cache.baca("P-003"));
    }
}
