【Java多线程】多线程之间实现通讯与生产者与消费者模式

Q:JAVA中如何实现线程通讯?

A:使用wait()、notify()、notifyAll()方法。

Q:什么是生产者与消费者模式?

A:假设有一间有最大容量的仓库,生产者生产商品存放在仓库,消费者购买商品从仓库中取货,仓库里货物为零时,消费者不能取出货物,仓库装满了,生产者不能继续生产货物。在程序中符合这种状态的模式称为生产者与消费者模式。


直接上代码

Test.java

/**
 * 实现了生产者与消费者之间的互动
 * @author Duxd
 *
 */

// 仓库类
class Storage{
	// 仓库的最大容量,能存放两件货物
	private final int MAX_SIZE = 2;
	
	// 规定仓库中最少要留一件货物
	private final int MIN_SIZE = 1;

	// 货物的载体
	private List<Object> storage = new ArrayList<Object>();
	

	// 仓库目前有多少件货物
	public int getStorageSize() {
		return storage.size();
	}
	
	// 往仓库放货物
	public void input(){ 
		storage.add(new Object());
	}
	
	// 从仓库拿出货物
	public void output(){
		storage.remove(0);
	}
	
	
	public int getMAX_SIZE() {
		return MAX_SIZE;
	}

	public int getMIN_SIZE() {
		return MIN_SIZE;
	}
}

// 生产者类
class Producer implements Runnable{
	private boolean flag = true;
	
	private Storage sto;
	
	public void stopProducerThread(){
		this.flag = false;
	}
	
	public Producer(Storage sto) {
		this.sto = sto;
	}
	@Override
	public void run() {
		while(flag) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			synchronized(sto) {
				if(sto.getStorageSize() < sto.getMAX_SIZE()){
					// 如果货物量小于仓库最大容量,生产货物
					sto.input();
					System.out.println("生产者:生产了货物,仓库目前货物量为" + sto.getStorageSize() + "。");
				}else {
					// 否则停止生产,等待消费
					System.out.println("生产者:仓库目前货物量为" + sto.getStorageSize() + ",停止生产。");
					try {
						sto.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				// 生产完了告诉消费者,仓库有货快来消费
				sto.notify();
			}
		}
	}
}

// 消费者类
class Consume implements Runnable{
	private boolean flag = true;
	
	private Storage sto;
	
	public Consume(Storage sto) {
		this.sto = sto;
	}
	
	public void stopConsumeThread(){
		this.flag = false;
	}
	
	@Override
	public void run() {
		while(flag) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			synchronized(sto) {
				if(sto.getStorageSize() > sto.getMIN_SIZE()) {
					// 如果货物量大于最少存货量,消费货物
					sto.output();
					System.out.println("消费者:消费了货物,仓库目前货物量为" + sto.getStorageSize() + "。");
				}else {
					// 否则停止消费,等待生产
					System.out.println("消费者:仓库目前货物量为" + sto.getStorageSize() + ",停止消费。");
					try {
						sto.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				// 消费完了告诉生产者,仓库没满快点生产
				sto.notify();
			}
		}
	}
}

public class Test {
	public static void main(String[] args) throws InterruptedException {
		// 单例,只有一间仓库
		Storage sto = new Storage();
		Producer producer = new Producer(sto);
		Consume consume = new Consume(sto);
		Thread tp = new Thread(producer);
		Thread tc = new Thread(consume);
		tp.start();
		tc.start();
		// 十秒后停止线程
		Thread.sleep(10000);
		producer.stopProducerThread();
		consume.stopConsumeThread();
	}
}

运行结果

消费者:仓库目前货物量为0,停止消费。
生产者:生产了货物,仓库目前货物量为1。
消费者:仓库目前货物量为1,停止消费。
生产者:生产了货物,仓库目前货物量为2。
消费者:消费了货物,仓库目前货物量为1。
生产者:生产了货物,仓库目前货物量为2。
消费者:消费了货物,仓库目前货物量为1。
生产者:生产了货物,仓库目前货物量为2。
消费者:消费了货物,仓库目前货物量为1。
生产者:生产了货物,仓库目前货物量为2。
生产者:仓库目前货物量为2,停止生产。
消费者:消费了货物,仓库目前货物量为1。
可以看到,当仓库里货物数量为零或等于最小留存量时,消费者停止了消费,等待生产。

生产者在要爆仓时,停止了生产,等待消费。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值