使用wait和notify方法实现生产者消费者模式

本文详细介绍了生产者消费者模式的概念及其实现方式。通过具体的Java代码示例,演示了如何利用wait和notify方法来实现线程间的同步,确保在多线程环境下能够正确地进行生产和消费操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 什么是“生产者和消费者模式”?
    生产线程负责生产,消费线程负责消费。
    这是一种特殊的业务需求,在这种特殊的情况下需要使用wait方法和notify方法。
  2. wait和notify方法不是线程对象的方法,是普通java对象都有的方法。
  3. wait方法和notify方法建立在线程同步的基础之上。因为多线程要同时操作一个仓库。有线程安全问题。
  4. wait方法作用: o.wait()让正在o对象上活动的线程t进入等待状态,并且释放掉t线程之前占有的o对象的锁。
  5. notify方法作用: o.notify()让正在o对象上等待的线程唤醒,只是通知,不会释放o对象上之前占有的锁。
  6. 模拟这祥一个需求:
    仓库我们采用List集合。
    List集合中假设只能存储1个元素。1个元素就表示仓库满了。
    如果List集合中元素个数是0,就表示仓厍空了。
    必须做到这种效果:生产1个消费1个。

实现

import java.util.ArrayList;
import java.util.List;

public class Test {

	public static void main(String[] args) {
		List list = new ArrayList();
		Thread t1 = new Procuder(list);
		Thread t2 = new Consumer(list);

		t1.setName("t1");
		t2.setName("t2");

		t1.start();
		t2.start();
	}
}

// 生产者类
class Procuder extends Thread {

	private List list;

	public Procuder(List list) {
		this.list = list;
	}

	@Override
	public void run() {
		// 死循环,表示一直生产
		while (true) {
			// 给仓库对象加锁
			synchronized (list) {
				// 大于0,说明仓库中已经有1一个元素了
				if (list.size() > 0) {
					try {
						// 让当前线程进入等待状态,并释放Producer之前占有的list对象的锁,使得下面的Consumer可以获得list的锁继续执行
						list.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// 程序能执行到这里,说明仓库是空的,应该生产一个商品
				Object obj = new Object();
				list.add(obj);
				System.out.println(Thread.currentThread().getName() + "生产" + obj);
				// 唤醒调用了list的wait方法的线程,注意当前有synchronized限制,所以消费者需要等到生产者出了synchronized代码块后才会执行
				list.notifyAll();
			}
		}
	}
}

// 消费者类类
class Consumer extends Thread {

	private List list;

	public Consumer(List list) {
		this.list = list;
	}

	@Override
	public void run() {
		// 死循环,表示一直消费
		while (true) {
			// 给仓库对象加锁
			synchronized (list) {
				// 等于0,说明仓库中没有元素可以消费
				if (list.size() == 0) {
					try {
						// 让当前线程进入等待状态,并释放Consumer之前占有的list对象的锁,使得上面的Procuder可以获得list对象的锁继续执行
						list.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// 程序能执行到这里,说明仓库是有元素的,应该消费一个商品
				Object obj = list.remove(0);
				System.out.println(Thread.currentThread().getName() + "消费" + obj);
				// 唤醒调用了list的wait方法的线程,注意当前有synchronized限制,所以消费者需要等到生产者出了synchronized代码块后才会执行
				list.notifyAll();
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值