public class MonitorPerObjek {
    // Flag volatile agar tulisan Budi langsung terlihat oleh Siti
    // (penjelasan lengkap ada pada Chapter volatile).
    private static volatile boolean budiDiDalam = false;

    public static void main(String[] args) throws InterruptedException {
        Object pintu1 = new Object(); // setiap objek punya intrinsic lock sendiri
        Object pintu2 = new Object();
        boolean[] bukti = new boolean[1];

        Thread budi = new Thread(() -> {
            synchronized (pintu1) {
                budiDiDalam = true;
                try {
                    Thread.sleep(300); // memegang lock pintu1 selama 300 ms
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                budiDiDalam = false;
            }
        }, "Budi");

        Thread siti = new Thread(() -> {
            try {
                Thread.sleep(100); // pastikan Budi sudah berada di dalam pintu1
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            }
            synchronized (pintu2) { // lock pintu2 berbeda: masuk tanpa menunggu
                bukti[0] = budiDiDalam; // true berarti Budi masih di dalam pintu1
            }
        }, "Siti");

        budi.start();
        siti.start();
        budi.join();
        siti.join();

        System.out.println("Siti masuk pintu-2 saat Budi masih di pintu-1: " + bukti[0]);
    }
}
