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 条评论
登录 后参与评论

相关文章

来自专栏张狗蛋的技术之路

MySQL探秘(三):InnoDB的内存结构和特性

 常言说得好,每个成功男人背后都有一个为他默默付出的女人,而对于MySQL来说,这个“人”就是InnoDB存储引擎。  MySQL区别于其他数据库的最为重要的特...

1062
来自专栏一个会写诗的程序员的博客

物理内存与虚拟内存

物理内存就是你的机器本身内存了(如内存条的大小)。物理内存就是CPU的地址线可以直接进行寻址的内存空间大小。比如8086只有20根地址线,那么它的寻址空间就是1...

552
来自专栏北京马哥教育

我所理解的性能测试是什么?

扯淡 首先说明这篇博客是文不对题的。起这个名字想法来源自韩寒的《我所理解的生活》,之前看过一个关于这本书的视频,感觉巨牛X,于是就想写一篇《我所理解的性能测试...

3609
来自专栏架构师之路

多库多事务降低数据不一致概率

一、案例缘起 我们经常使用事务来保证数据库层面数据的ACID特性。 举个栗子,用户下了一个订单,需要修改余额表,订单表,流水表,于是会有类似的伪代码: star...

2795
来自专栏linjinhe的专栏

MySQL半同步复制

MySQL通过复制(Replication)实现存储系统的高可用。目前,MySQL支持的复制方式有:

2525
来自专栏乐沙弥的世界

Oracle DB Time 解读

Oracle DB Time是Oracle数据库在时间维度上剖析性能的一个重要指标,通过逐级分解该指标,定位到浪费资源或者资源争用的首要事件上,从而通过减少等待...

371
来自专栏用户画像

7.4.2 程序中断方式

程序中断是指在计算机执行现行程序的过场中,出现某些急需处理的异常情况或特殊请求,CPU暂停中断现行程序,而专区对这些异常情况或特殊情况进行处理,在处理完毕后CP...

461
来自专栏有困难要上,没有困难创造困难也要上!

Apache-Ignite入门实战之三 - 分布式锁

3187
来自专栏用户2442861的专栏

编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程

什么是线程?线程与进程与有什么关系?这是一个非常抽象的问题,也是一个特别广的话题,涉及到非常多的知识。我不能确保能把它讲的话,也不能确保讲的内容全部都正确。即...

261
来自专栏文渊之博

SQLServer 延迟事务持久性

SQL Server 2014新功能 -- 延迟事务持久性(Delayed Transaction Durability) SQL Server事务提交默认...

1988

扫码关注云+社区