使用Object对象的wait和notify来实现一个生产者消费者模型

今天学习Object的wait和notify。使用这两个方法实现一个生产者、消费者模型

首先定义一个仓库类,因为生产者还是消费者,都要从仓库存或者取

public class Storage {
    // 仓库的最大容量
    private int maxSize;
    // 具体的仓库
    private LinkedList<Date> storage;

    public Storage() {
        this.maxSize = 10;
        this.storage = new LinkedList<>();
    }

    /**
     * 往仓库放产品
     * synchronized 放在方法上,那么该方法获取的就是当前对象的锁
     */
    public synchronized void put() {
        // 检测仓库是否满了,如果满了,就通知消费者取东西(释放锁)
        while(this.storage.size() == maxSize) {
            // 释放当前对象的锁
            try {
                wait();
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.storage.add(new Date());
        System.out.println("仓库中有了" + storage.size() + "个产品");
        // 仓库中有了产品,就唤醒其他线程,来消费产品,本例中只有两个线程,
        // 一个生产者、一个消费者,故,此处唤醒的就是消费者了
        notify();
    }

    /**
     * 消费仓库中的产品
     */
    public synchronized void take() {
        // 检测仓库中是否有产品,有就消费,没有就等待
        while(this.storage.size() == 0) {
            try {
                // 由于仓库中没有东西,所以,就把锁释放了,让生产者获得锁,去生产
                wait();
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("消费者消费了:" + this.storage.poll() + ",目前还剩下:" + this.storage.size()+ "个产品");
        // 消费者消费了产品,就通知生产者继续生产
        notify();
    }
}

定义生产者类

/**
 * 生产者类
 */
public class Producer implements Runnable {
	// 需要仓库去放产品
	private Storage storage;
	public Producer(Storage storage) {
		this.storage = storage;
	}
	@Override
	public void run() {
		// 生产100个产品
		for (int i = 0; i < 100; i++) {
            storage.put();
        }
	}
}

定义消费者类

/**
 * 消费者
 */
public class Consumer implements Runnable {
	private Storage storage;
	public Consumer(Storage storage) {
		this.storage = storage;
	}

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
            storage.take();
        }
	}
}

主函数

public class ProducerConsumerModerByWaitAndNotify {
	public static void main(String[] args) {
		Storage storage = new Storage();
        Thread producer = new Thread(new Producer(storage));
        Thread consumer = new Thread(new Consumer(storage));
        producer.start();
        consumer.start();
	}
}

运行结果如下

仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品
仓库中有了1个产品
仓库中有了2个产品
仓库中有了3个产品
仓库中有了4个产品
仓库中有了5个产品
仓库中有了6个产品
仓库中有了7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
仓库中有了8个产品
仓库中有了9个产品
仓库中有了10个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:9个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:8个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:7个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:6个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:5个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:4个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:3个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:2个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:1个产品
消费者消费了:Sun Jan 05 21:10:15 CST 2020,目前还剩下:0个产品

Process finished with exit code 0

总结

waitnofity只能用在synchronized关键字包围的代码块中,synchronized能够获取一个对象的锁,而当我们调用了wait()方法后,正在执行到wait方法的线程就会等待,也就是释放了已经获取到的monitor锁,一直等到其他线程使用nofity()或者notifyAll()方法来唤醒他,那么他就会再次阻塞状态,等待CPU调度,获取到锁。

发布了33 篇原创文章 · 获赞 24 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Myc_CSDN/article/details/103847113