Java中通过wait和notify来实现生产者和消费者模式

今天通过介绍一下如何通过wait和notify来实现生产者和消费者模式。

通过synchronized同步代码块实现线程的同步操作,从而保证数据的一致性。下面具体介绍一下这个模式的实现过程。

1.首先编写一个生产者类:

public class Producer implements Runnable {
	private PublicBox box;

	public Producer(PublicBox box) {
		this.box = box;
	}

	@Override
	public void run() {
		int i=0;
		while(true){
			try {
				System.out.println("生产者序号:" + i);
				i++;
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			box.increace();
		}
	}
}

2.其次编写一个消费者类:

public class Consumer implements Runnable {
	private PublicBox box;

	public Consumer(PublicBox box) {
		this.box = box;
	}

	@Override
	public void run() {
		int i=0;
		while(true){
			try {
				System.out.println("消费者序号" + i);
				i++;
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO: handle exception
				e.printStackTrace();
			}

			box.decreace();
		}
	}
}

3.最后编写仓库类:

public class PublicBox {
	private int product = 0;

	public synchronized void increace() {
		while (product == 5) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
		product++;
		System.out.println("产品生产成功!目前产品的存储量:"+product);
		notify();
	}

	public synchronized void decreace() {
		while (product == 0) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		product--;
		System.out.println("产品消费成功!目前产品的存储量:"+product);
		notify();
	}

	public static void main(String[] args) {
		PublicBox box = new PublicBox();
		Consumer con = new Consumer(box);
		Producer pro = new Producer(box);
		Thread t1 = new Thread(con);
		Thread t2 = new Thread(pro);
		t1.start();
		t2.start();
	}
}

打印出来的部分结果:

这个执行过程有些人可能会有些疑问,我在这里具体描述一下这整个过程是如何实现的。

在这里因为生产者所休眠的时间比消费者短,所以生产者出现的频率会比消费者高一些。

1:首先是生产者和消费者都新建了各自的序号并打印出来。

2:因为是消费者先启动的,所以首先访问decreace同步块,可是因为条件不符合所以被wait了。

3:消费者被wait之后,生产者就开始启动increace同步块生产了。生产者一生产就会调用notify方法,这个时候第二步已经被wait的线程就会被唤醒,接着执行wait之后的代码。但是这里需要注意的是并不是生产者调用notify方法,消费者就会马上被唤醒执行接下来的代码。因为唤醒和执行都需要时间,这个过程可能生产者又生成新的产品了吗,也有可能是消费者马上被执行。

4:之后的过程就是按照前面三步骤进行循环输出的。

这个模式下的生产者消费者主要是通过synchronized 同步代码块来保证product这个变量的一致性。保证product变量在多个线程的调用的过程中,线程之间不会发生互相干扰,按正确的顺序执行这些过程。

如果对上面的内容还有什么疑义或者问题都可以加我QQ:208017534咨询。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猛牛哥的博客

快手(AAU)更新记录v2.9.1.12

1533
来自专栏Kevin-ZhangCG

[ Java面试题 ]WEB篇

1918
来自专栏性能与架构

Redis案例 - 事件提醒

场景 任务是 当 redis set 中有新元素时及时处理 需要在set有新元素后自动得到通知,省得使用轮询的方式来查看是否有新元素 相当于对set做一...

3368
来自专栏平凡文摘

11 个简单的 Java 性能调优技巧

1292
来自专栏后台全栈之路

基于汇编的 C/C++ 协程 - 切换上下文

既然本系列讲的是基于汇编的 C/C++ 协程,那么这篇文章我们就来讲讲使用汇编来进行上下文切换的原理。

2326
来自专栏木可大大

漫谈虚拟内存

如上图,程序1、程序2、程序3装入到内存,而程序2运行完成被换出,内存空闲出20k,然后进来程序4,大小为25K,此时,只有两处空闲块,10K和20K,没有一处...

4814
来自专栏CSDN技术头条

Java性能调优的11个实用技巧

大多数开发人员认为性能优化是个比较复杂的问题,需要大量的经验和知识。是的,这并不没有错。诚然,优化应用程序以获得最好的性能并不是一件容易的事情,但这并不意味着你...

1737
来自专栏Python专栏

python的生产者消费者模型,看这篇就够了

2025
来自专栏java一日一条

11 个简单的 Java 性能调优技巧

大多数开发人员理所当然地以为性能优化很复杂,需要大量的经验和知识。好吧,不能说这是完全错误的。优化应用程序以获得最佳性能不是一件容易的事情。但是,这并不意味着如...

832
来自专栏Albert陈凯

Storm Trident State 三种事务

原文链接 译者:魏勇 Trident 中含有对状态化(stateful)的数据源进行读取和写入操作的一级抽象封装工具。这个所谓的状态(state)既可以保...

3296

扫码关注云+社区