📜  监视器与信号量(1)

📅  最后修改于: 2023-12-03 15:11:21.940000             🧑  作者: Mango

监视器与信号量

监视器

监视器是一种同步机制,它用于控制多线程之间的互斥访问。Java 中的每个对象都是一个监视器,你可以利用 synchronized 关键字来获得对这个监视器的锁定。

指定 synchronized 关键字的方法或代码块一次只能被一个线程进入,其他线程必须等待该线程退出这个方法或代码块.

可以使用 wait() 和 notify()/notifyAll() 方法来实现线程之间的通信。wait() 方法会使当前线程等待,直到另一个线程调用该对象的 notify()/notifyAll() 方法来唤醒它。

public class MonitorDemo {
    public synchronized void print(String str) {
        System.out.print("[");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.print(str);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("]");
    }

    public static void main(String[] args) {
        MonitorDemo demo = new MonitorDemo();
        Runnable r = () -> {
            demo.print(Thread.currentThread().getName());
        };
        new Thread(r, "A").start();
        new Thread(r, "B").start();
    }
}
信号量

信号量是一种同步机制,用于管理多个线程之间的访问。与监视器不同,信号量可以限制线程的数量。当信号量的计数器为零时,任何试图获取信号量的线程将被阻塞,直到有一个线程释放了信号量。

Java 中的 Semaphore 类实现了信号量。你可以使用 Semaphore 的 acquire() 和 release() 方法来获取和释放信号量。

public class SemaphoreDemo {
    private final Semaphore semaphore = new Semaphore(2);

    public void print(String str) {
        try {
            semaphore.acquire();
            System.out.print("[");
            Thread.sleep(1000);
            System.out.print(str);
            Thread.sleep(1000);
            System.out.println("]");
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SemaphoreDemo demo = new SemaphoreDemo();
        Runnable r = () -> {
            demo.print(Thread.currentThread().getName());
        };
        new Thread(r, "A").start();
        new Thread(r, "B").start();
        new Thread(r, "C").start();
    }
}