美文网首页
使用wait和notify模拟生产者和消费者

使用wait和notify模拟生产者和消费者

作者: 鱿鱼炸酱面 | 来源:发表于2022-01-23 16:06 被阅读0次
    wait()和notify()

    wait()和notify()的方法并不是线程对象专属的方法,Java中所有的对象都有这两个方法。
    object.wait(): 持有obj对象锁的当前线程进入等待状态,并释放该对象的锁。
    object.notify(): 唤醒之前进入等待状态的线程,使这些线程重新尝试获取对象锁。

    模拟生产者和消费者模式

    仓库,生产者,消费者三者之间,常常达到供需平衡的状态,即:
    生产者生产指定量的产品,便不能生产(wait),需要通知消费者进行消费(notify);
    消费者消费完所有库存,便不能再消费(wait),需要告知生产者进行生产(notify)。
    如下代码模拟以上模式:

    import java.util.ArrayList;
    import java.util.List;
    
    public class ConsumerAndProducerTest {
        public static void main(String[] args) {
            // 模拟仓库
            List<Integer> list = new ArrayList<>();
            // 创建生产者线程
            Thread producer = new Thread(new Producer(list), "生产者");
            // 创建消费者线程
            Thread consumer = new Thread(new Consumer(list), "消费者");
            // 同时启动生产者和消费着
            producer.start();
            consumer.start();
        }
    }
    
    
    /**
     * 消费者类
     */
    class Consumer implements Runnable {
        final List<Integer> list;
        int number = 0;
    
        public Consumer(List<Integer> list) {
            this.list = list;
        }
    
        @Override
        public void run() {
            synchronized (list) {
                while (true) {
                    // 判断仓库中商品是否空了
                    if (list.size() == 0) {
                        try {
                            list.wait();  // 没有商品,进入等待状态并释放锁
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 消费库存中第一件商品,并返回商品编号
                    int id = list.remove(0);
                    System.out.println(Thread.currentThread().getName() + "消费了商品" + id + String.format(",已消费%d件商品!", ++number));
                    // 唤醒其他线程
                    list.notifyAll();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }
    
    
    /**
     * 生产者类
     */
    class Producer implements Runnable {
        final List<Integer> list;
        int id = 0;
    
        public Producer(List<Integer> list) {
            this.list = list;
        }
    
        @Override
        public void run() {
            synchronized (list) {
                while (true) {
                    // 判断仓库中商品是否有指定数量库存
                    if (list.size() >= 2) {
                        try {
                            list.wait();  // 有商品,进入等待状态并释放锁
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 生产
                    list.add(++id);
                    System.out.println(Thread.currentThread().getName() + "生产了商品" + id + String.format(", 现仓库有%d件未售出!", list.size()));
                    // 唤醒其他线程
                    list.notifyAll();
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:使用wait和notify模拟生产者和消费者

          本文链接:https://www.haomeiwen.com/subject/fhbmhrtx.html