Wait_Notify_NotifyAll

Wait_Notify_NotifyAll

wait、notify、notifyAll 机制是在Java 的 Object 对象里面的

  1. wait 是让当前线程释放锁,保存运行状态,然后进入等待状态
  2. notify 是唤醒当前处于等待状态的一个线程(随机唤醒)
  3. notifyAll 是唤醒当前处于等待状态的所有线程

注意:调用 wait/notify/notifyAll 方法,必须放在同步代码块或者同步代码方法里面执行

Wait() 方法

wait() 方法会释放当前的锁

注意:调用wait()方法时,当前对象是必须持有锁的,并且锁的对象 和 wait 方法使用的是同一个对象

synchronized(obj){
   obj.wait()
}

Notify() 方法

调用 notify() 方法,线程并不是可以立即获取锁,而是进入就绪状态(Ready),等待系统调用

notify() 方法,会唤醒等待状态的一个线程(随机唤醒),被唤醒之后,接着向下运行,并不是重新执行(上次执行数据会存放在PC寄存器中,等待下次继续执行)

注意:调用 notify() 方法,必须放在同步代码块或者同步代码方法里面执行

NotifyAll() 方法

notifyAll() 方法,会唤醒所有等待状态下的线程。

注意:调用 notifyAll() 方法,必须放在同步代码块或者同步代码方法里面执行

生产者/消费者模型

演示代码

/**
 * 生产者/消费者模型,使用 wait 、 notify 实现
 */
public class T01_Producer_Consumer {

    private static final int MAX_COUNT = 10;

    private static int no = 1;

    /**
     * 库存
     */
    private static Queue<String> inventoryQueue = new PriorityQueue();

    /**
     * 生产产品
     */
    synchronized void produceTea() throws InterruptedException {
        while (inventoryQueue.size() >= MAX_COUNT) {
            System.out.println("库房已满,机器停止生产,现有:"+inventoryQueue.size());
            wait();
        }

        //睡眠1秒,防止太快
        TimeUnit.SECONDS.sleep(1);

        String title = "Tea"+ (no++);
        inventoryQueue.add(title);
        System.out.println(Thread.currentThread().getName() + "生产产品:" + title+ " 现存:"+inventoryQueue.size());
        notify();
    }

    /**
     * 消费产品
     */
    synchronized void consumeTea() throws InterruptedException {
        while (inventoryQueue.size() <= 0) {
            System.out.println("库存已经没有啦,等待机器生产");
            wait();
        }
        //睡眠1秒,防止太快
        TimeUnit.SECONDS.sleep(1);

        System.out.println(Thread.currentThread().getName() + "消费产品:" + inventoryQueue.poll()+ " 剩余:"+inventoryQueue.size());
        notify();
    }

    public static void main(String[] args) {
        T01_Producer_Consumer test = new T01_Producer_Consumer();
        new Thread(() -> {
            while (true) {
                try {
                    test.produceTea();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "机器").start();
        new Thread(() -> {
            while (true) {
                try {
                    test.consumeTea();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "客人").start();
    }
}

演示结果

机器生产产品:Tea1 现存:1
机器生产产品:Tea2 现存:2
机器生产产品:Tea3 现存:3
机器生产产品:Tea4 现存:4
机器生产产品:Tea5 现存:5
机器生产产品:Tea6 现存:6
机器生产产品:Tea7 现存:7
机器生产产品:Tea8 现存:8
机器生产产品:Tea9 现存:9
机器生产产品:Tea10 现存:10
库房已满,机器停止生产,现有:10
客人消费产品:Tea1 剩余:9
客人消费产品:Tea10 剩余:8
客人消费产品:Tea2 剩余:7
客人消费产品:Tea3 剩余:6
客人消费产品:Tea4 剩余:5
客人消费产品:Tea5 剩余:4
客人消费产品:Tea6 剩余:3
客人消费产品:Tea7 剩余:2
客人消费产品:Tea8 剩余:1
客人消费产品:Tea9 剩余:0
库存已经没有啦,等待机器生产
机器生产产品:Tea11 现存:1
机器生产产品:Tea12 现存:2
机器生产产品:Tea13 现存:3
posted @ 2022-12-07 22:03  Cool_Yang  阅读(17)  评论(0编辑  收藏  举报