Java实现生产者和消费者问题

关于生产者和消费者的问题模型这里就不再详细描述
这里首先要定义三个类来分别代表生产者和消费者以及要生产或消费的物品
Producer.java
Consumer.java
Product.java
我们简单这么实现,假设生产者生产饼干或饮料当生产者生产完毕后通知消费者进行消费,当消费者消费完之后就通知生产者继续进行生产
实现如下:

生产者Producer.java

public class Producer implements Runnable {

	public Product pro;
	public Producer(Product pro){
		this.pro = pro;
	}
	
	@Override
	public void run() {
	// 生产者生产50次并控制让其在偶数次生产饼干,奇数次生产饮料
		for(int i = 0; i < 50; i ++){
			if(i % 2 == 0){
				pro.set("饼干");
			}else{
				pro.set("饮料");
			}
		}
	}
}
消费者Consumer.java

public class Consumer implements Runnable {

	private Product pro;
	public Consumer(Product pro){
		this.pro = pro;
	}
	@Override
	public void run() {
		// 消费者消费50次
		for(int i = 0; i < 50; i ++){
			pro.get();
		}
	}
}
产品Product.java

public class Product {

	// 所生产的产品
	private String product;

	// 定义信号量,是否有产品,默认为空即true
	private boolean isEmpty = true;

	public String getProduct() {
		return product;
	}

	public void setProduct(String product) {
		this.product = product;
	}

	// 生产
	public void produce(String product) {
		synchronized (this) {
			while (!isEmpty) {
				// 如果不为空,等待消费者消费
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			this.setProduct(product);
			System.out.println("生产者生产------>" + this.getProduct());
			isEmpty = false;
			this.notify();
		}

	}

	// 消费
	public void consume() {
		synchronized (this) {
			while (isEmpty) {
				// 如果为空,等待生产者生产
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("消费者消费------>" + this.getProduct());
			isEmpty = true;
			this.notify();
		}
	}
}

使用main方法进行测试
Test.java

public class Test {

	public static void main(String[] args) {
		// 产品
		Product pro = new Product();
		// 定义一个生产者
		Producer producer = new Producer(pro);
		// 定义一个消费者
		Consumer consumer = new Consumer(pro);
		// 启动生产者线程
		new Thread(producer).start();
		// 启动消费者线程
		new Thread(consumer).start();
	}
}

执行结果:
生产者生产------>饼干
消费者消费------>饼干
生产者生产------>饮料
消费者消费------>饮料
生产者生产------>饼干
消费者消费------>饼干
生产者生产------>饮料
消费者消费------>饮料
.....

即生产者每生产一次,就会通知消费者消费一次,消费者消费完之后,就会通知生产者继续生产
我这里采用的是一个生产者和一个消费者的情况,对于多个生产者和多个消费者的情况,其实就是多启动几个生产者和消费者线程,此外程序需要将唤醒线程的方法改为:notifyAll

这里需要注意的是wait()、notify()、notifyAll(),这三个方法属于Object 不属于 Thread,这三个方法必须由同步监视对象来调用,即调用wait、notify、notifyAll方法的对象必须是synchronized所监视的对象

在上面我们采用了synchronized来进行线程的同步实现了生产者和消费者问题,现在我们采用jdk1.5版本以上采用的同步锁进行一次实现,同步锁和synchronized的效果一样都能够实现线程的同步,同时其功能更加强大。现在我们就用同步锁的方式来实现一下生产这和消费者问题,与之前不同的是这里要解决的一个问题就是,线程之间的通信怎么进行处理,由于同步锁没有像synchronized一样存在对固定对象的监视,因此wait、notify、notifyAll都不能再使用了。这里同步锁提供了另外的可代替的方式,就是Condition,Condition通过Lock的对象的newCondition方法产生,可起到同步监视器的作用。简单的说:Lock代替了同步方法或同步代码块,Condition代替了同步监视器的功能

下面我们就将之前的实现进行一下修改:
生产者:Producer.java
消费者:Consumer.java
都不用变

Product.java修改如下

public class Product {

	// 产品
	private String product;
	
	// 定义信号量,是否有产品
	private boolean isEmpty = true;

	// 定义同步锁
	private final ReentrantLock lock = new ReentrantLock();
	// 获取Condition对象
	private final Condition condition = lock.newCondition();

	public String getProduct() {
		return product;
	}

	public void setProduct(String product) {
		this.product = product;
	}

	// 生产
	public void produce(String product) {
		lock.lock();
		try {
			while (!isEmpty) {
				// 等待消费者消费
				condition.await();
			}
			this.setProduct(product);
			System.out.println("生产者生产------>" + this.getProduct());
			isEmpty = false;
			condition.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	// 消费
	public void consume() {
		lock.lock();
		try {
			while (isEmpty) {
				// 等待生产者生产
				condition.await();
			}
			System.out.println("消费者消费------>" + this.getProduct());
			isEmpty = true;
			condition.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

使用main方法测试和之前的结果一致

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值