public class BlokSynchronized {
    private static class Kas {
        private long saldo = 0;

        // Objek lock privat: tidak ada kode luar yang bisa mengunci objek ini.
        private final Object kunci = new Object();

        void setor(long jumlah) {
            // Validasi berjalan di luar lock: bagian non-kritis tetap paralel.
            if (jumlah <= 0) {
                return;
            }
            synchronized (kunci) {
                // Bagian kritis: baca-hitung-tulis saldo sebagai satu kesatuan.
                long baca = saldo;
                saldo = baca + jumlah;
            }
        }

        long bacaSaldo() {
            synchronized (kunci) {
                return saldo;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Kas kas = new Kas();
        Runnable tugas = () -> {
            for (int i = 0; i < 100_000; i++) {
                kas.setor(1);
            }
        };
        Thread a = new Thread(tugas, "teller-A");
        Thread b = new Thread(tugas, "teller-B");
        a.start();
        b.start();
        a.join();
        b.join();
        System.out.println("saldo akhir: " + kas.bacaSaldo());
    }
}
