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

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();
                }
            }

        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。