【设计模式】生产者消费者模式

线程:生产者和消费者问题(序列图) 生产者和消费者问题: 名字 说明 Cake 蛋糕类 Panzi 蛋糕的队列 ProducerThread 生产蛋糕的线程 ConsumerThread 消费蛋糕的线程 Main 测试类 Sequence序列图: 对于同步和异步的控制都是在Panzi 阅读详情

生产消费者模型

生产者消费者模型具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品。生产消费者模式如下图。
这里写图片描述
  在日益发展的服务类型中,譬如注册用户这种服务,它可能解耦成好几种独立的服务(账号验证,邮箱验证码,手机短信码等)。它们作为消费者,等待用户输入数据,在前台数据提交之后会经过分解并发送到各个服务所在的url,分发的那个角色就相当于生产者。消费者在获取数据时候有可能一次不能处理完,那么它们各自有一个请求队列,那就是内存缓冲区了。做这项工作的框架叫做消息队列。
#生产者消费者模型的实现
  生产者是一堆线程,消费者是另一堆线程,内存缓冲区可以使用List数组队列,数据类型只需要定义一个简单的类就好。关键是如何处理多线程之间的协作。这其实也是多线程通信的一个范例。

在这个模型中,最关键就是内存缓冲区为空的时候消费者必须等待,而内存缓冲区满的时候,生产者必须等待。其他时候可以是个动态平衡。值得注意的是多线程对临界区资源的操作时候必须保证在读写中只能存在一个线程,所以需要设计锁的策略。

第一种:使用wait-notify

public class ProducerAndConsumer {

	// 作为synchronized的对象监视器
	private static Object lock = new Object();
	// 随机数
	private static Random random = new Random();
	
	static class Producer implements Runnable {

		private Queue queue;
		
		public Producer(Queue queue) {
			this.queue = queue;
		}
		
		@Override
		public void run() {
			while(true) {
				synchronized(lock) {
					try {
						Thread.sleep(500);
						
						// 超过规定的队列长度,停止生产
						if(queue.size() >= 10) {
							lock.wait();
						}
						
						// 生产
						int i = random.nextInt(100);
						queue.add(i);
						System.out.println(Thread.currentThread().getName() + "已生产:" + i);
						
						// 生产完后队列不为空,唤醒消费者
						lock.notify();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	static class Consumer implements Runnable {

		private Queue queue;
		
		public Consumer(Queue queue) {
			this.queue = queue;
		}
		
		@Override
		public void run() {
			while(true) {
				synchronized(lock) {
					try {
						Thread.sleep(600);
						
						// 如果队列为空,则让消费者进入等待状态
						if(queue.isEmpty()) {
							lock.wait();
						}
						
						// 消费
						System.out.println(Thread.currentThread().getName() + "已消费:" + queue.poll());
						
						// 消费完后,唤醒生产者
						lock.notify();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void main(String[] args) {
		// 队列
		Queue queue = new LinkedList();
		
		new Thread(new Producer(queue), "生产者1号").start();
		new Thread(new Producer(queue), "生产者2号").start();
		new Thread(new Consumer(queue), "消费者1号").start();
		new Thread(new Consumer(queue), "消费者2号").start();
	}
}

第二种:使用阻塞队列

阻塞队列的特点:

  • 当队列元素已满的时候,阻塞插入操作
  • 当队列元素为空的时候,阻塞获取操作

ArrayBlockingQueue与LinkedBlockingQueue都是支持FIFO(先进先出)

ArrayBlockingQueue 是有界的,而 LinkedBlockingQueue 是无界的

public class ProducerAndConsumer02 {

	// 随机数
	private static Random random = new Random();
	
	static class Producer implements Runnable {

		private BlockingQueue queue;
		
		public Producer(BlockingQueue queue) {
			this.queue = queue;
		}
		
		@Override
		public void run() {
			while(true) {
				try {
					Thread.sleep(500);
					
					// 生产
					int i = random.nextInt(100);
					queue.put(i);
					System.out.println(Thread.currentThread().getName() + "已生产:" + i);
					
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	static class Consumer implements Runnable {

		private BlockingQueue queue;
		
		public Consumer(BlockingQueue queue) {
			this.queue = queue;
		}
		
		@Override
		public void run() {
			while(true) {
				try {
					Thread.sleep(600);
					
					// 消费
					System.out.println(Thread.currentThread().getName() + "已消费:" + queue.take());
				
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		// 队列
		BlockingQueue queue = new ArrayBlockingQueue(10);
		
		new Thread(new Producer(queue), "生产者1号").start();
		new Thread(new Producer(queue), "生产者2号").start();
		new Thread(new Consumer(queue), "消费者1号").start();
		new Thread(new Consumer(queue), "消费者2号").start();
	}
}
【LabVIEW学习篇 - 24】:生产者/消费者设计模式 生产者/消费者是多线程编程中最基本的一种模式,使用非常普遍。从软件角度看,生产者就是数据的提供方,而消费者就是数据的消费处理方,二者之间存在一个数据缓存区。 阅读详情

相关推荐

线程的消息队列的代码资源

线程的消息队列 线程的消息队列 线程的消息队列 线程的消息队列

线程学习(三)---生产消费模型

线程学习(三)---生产消费模型什么是生产消费模型生产消费模型图例生产消费模型解释wait()/notify() notifyAll()与sleep()的区别线程生命周期图分析sleep()方法wait()、notify()、notifyAll()方法用wait()/notify()实现生产消费模型生产消费模型的设计思路代码实现 什么是生产消费模型 生产消费模型图例 生产消费模型解释 由图例可知,生产消费模型由三个部分组成生产者、消费者、缓冲容器。生产者线程不断产生数据并存储在缓冲容器中,而消费者不断从缓

nooooooooooooo的博客 395

戴维南和诺顿定理到底怎么选?一个实际维修案例讲透两种等效电路用法

本文通过工业电源模块维修案例,详细解析戴维南和诺顿定理在实际电路分析中的选择策略。针对电压敏感型故障、电流分配问题及功率传输异常,提供三大黄金法则,帮助工程师高效选择等效电路方法,提升故障排查效率。特别强调诺顿定理在电流分析中的优势。

weixin_31854867的博客 357

生产者与消费者模型

一、生产与消费者模型 1、基本概念模型 生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,模型图如下所示: 2、必须具有的条件 (1) 三种关系:三种关系分别指的是:消费者和消费者,生产者和生产者,生产者和消费者;其中消费者和消费者,生产者和生产者之间都属于竞争关系,生产者和消费者之间的关系相当于是一种食物链之间的依赖关系。 ...

everthing willl be ok 2459

ASReview:基于主动学习的AI文献筛选工具,提升科研效率

主动学习是机器学习的一个重要分支,其核心原理是让算法能够主动选择最有价值的数据进行标注,从而以更低的成本获得更好的模型性能。这一技术通过人机协作的闭环流程,显著提升了数据标注和模型训练的效率和精度。在工程实践中,主动学习尤其适用于数据标注成本高昂或数据类别不平衡的场景,例如医学影像分析、自然语言处理中的文本分类以及推荐系统的冷启动问题。通过优先标注模型最不确定的样本,它能够有效解决传统机器学习面临的冷启动和数据稀疏性挑战。本文聚焦的ASReview项目,正是将主动学习原理应用于系统文献综述这一具体场景,通过

weixin_28725959的博客 431

基于文件通信的QMT量化交易信号桥接方案设计与实现

在量化交易系统开发中,进程间通信(IPC)是连接不同计算模块、实现策略逻辑与交易执行解耦的关键技术。其核心原理在于允许运行于独立环境或进程的程序安全、可靠地交换数据。文件系统通信作为一种经典的IPC方法,因其实现简单、跨平台兼容性好且数据可持久化,在非高频场景下具有重要技术价值。它尤其适用于需要将外部复杂计算环境(如配备丰富数据科学库的Python环境)与专用交易终端(如迅投QMT)集成的应用场景。通过约定文件路径与数据格式,外部程序可将包含交易指令的JSON信号文件写入特定目录,而交易终端通过轮询或监听机

weixin_28678151的博客 417

【C++】【设计模式之】生产者-消费者模型(理论讲解及实现)

一、什么是生产者-消费者模型 1、简单理解生产者-消费者模型 假设有两个进程(或线程)A、B和一个固定大小的缓冲区,A进程生产数据放入缓冲区,B进程从缓冲区中取出数据进行计算,这就是一个简单的生产者-消费者模型。这里的A进程相当于生产者,B进程相当于消费者。 2、为什么要使用生产者-消费者模型 在多线程开发中,如果生产者生产数据的速度很快,而消费者消费数据的速度很慢,那么生产者就必须等待消费者消费完数据才能够继续生产数据,因为生产过多的数据可能会导致存储不足;同理如果消费者的速度大于生产者那么消费者就会经常

格物致知 1万+

PCB板质量测试和PCB板

PCB板质量测试和板厂

weixin_51370842的博客 515

设计模式——生产者消费者模式

1 基本概括 2 主要介绍 2.1 概念 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力 这个阻塞队列就是用来给生产者和消费者解耦的。 如果缓冲区已经满了,则生产者线程阻塞; 如果缓冲区为空,那么消费者线程阻塞。 2.2 生产消费者模型 就是在一

qq_20761351的博客 1万+

Carla-UE4Editor导入RoadRunner地图文件(保姆级教程)

以Carla官网导入RoadRunner地图的标准文档为参考,里面增添了很多细节和注意事项,遇到问题的小伙伴过来看看吧。

DSK_981029的博客 1万+

044、Edge Impulse的音频分类实战

上周调试一块STM32WBA52开发板,板载PDM麦克风死活采不到有效数据。示波器怼上去,时钟线波形漂亮得像教科书,数据线却像心电图——全是毛刺。折腾半天发现是电源纹波干扰,给麦克风单独加了个LC滤波,世界清净了。这种坑,做音频分类的嵌入式工程师迟早要踩一遍。

2401_88858637的博客 54

Android之生产者/消费者设计模式解释

去过机场的人应该都会看到放行李的传送带,工作人员将托运的行李不停的放入传送带,乘客下飞机之后会不停的拿走行李。 这个例子和生产者/消费者设计模式相似。 这种设计模式需要满足以下三点要求: (1)生产者生产数据到缓冲区中,消费者从缓冲区中取数据。 (2)如果缓冲区已经满了,则生产者线程阻塞; (3)如果缓冲区为空,那么消费者线程阻塞。 编写之前分析: (1)定义一个缓存队列,选择一个集合当做...

haigand的专栏 1956

YOLO26中 RepVGGBlock_OREPA 架构的设计与性能提升分析(mAP +4.89)

REPVGGOREPA模块代表了重参数化技术的最新发展,它通过巧妙的架构设计实现了训练时的丰富表达和推理时的高效计算。其核心创新包括多分支特征聚合、动态权重生成、频域先验知识融合等技术,为深度学习模型的效率优化提供了新的解决方案。这种设计理念不仅在技术上具有重要意义,在实际应用中也展现出了显著的优势,特别是在需要高精度和高效率的工业场景中表现突出。随着重参数化技术的不断发展,REPVGGOREPA为未来的网络架构设计提供了重要的参考和启发。

know_F0727的博客 66

生产者消费者设计模式

生产者消费者设计模式 概述 有两个线程生产者和消费者,有一个任务队列(有大小限制,太大了阻塞当前的生产者,不让其生产)。队列中有put和take方法。 put方法时将消息(Message)放入队列中,唤醒消费者进行消费 take拿出一个消息进行消费。唤醒生产者可以生产。 代码实现如下 1.编写Message消息类 public class Message { private String data; public Message(String data) { this.

雨天的麦子的博客 467

连接参数详解:Connection Interval, Slave Latency, Supervision Timeout 的协同与调优实战

在低功耗蓝牙(BLE)开发与调试中,Connection Interval(连接间隔)、Slave Latency(从机延迟) 和 Supervision Timeout(监督超时) 是三个核心参数。它们不仅直接影响设备的通信性能、功耗表现和连接稳定性,更是各类技术面试与认证考试的高频考点。本文将从基础概念出发,深入剖析三者的协同机制,结合历年真题解析考点与解题思路,并通过实战案例演示调优方法,快速掌握这一核心知识点。

byte轻骑兵的技术小窝 2761

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【Java】设计模式之生产者/消费者

这个设计模式使用一个消息队列对生产者和消费者进行解耦。它与保护性暂停最大的区别就是它并不需要产生结果者与消费结果者一一对应,而是可以多对多。而且这个设计模式它传递消息会存在一定的延迟,而保护性暂停传递信息是十分及时的。消费者从消息队列中取消息,如果消息队列为空,消费者会进入阻塞状态;如果消息队列不为空,消费者会取出消息队列头的消息然后唤醒所有生产者。生产者将消息放入消息队列中直到消息队列满,这时候生产者会进入阻塞状态;如果消息队列不满,生产者将消息放入消息队列后会唤醒所有的消费者。

第三季度的博客 665

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

高并发设计模式之生产者-消费者模式和Future模式

生产者和消费者是两个独立的并发体,生产者把制造出来的数据往缓冲区一放,就可以生产下一个数据.生产者基本上不用依赖于消费者的消费速度.如果生产过快,消费者可以平缓的进行处理.比如阻塞队列和MQ等就是生产者消费的例子.Future模式的核心思想是异步调用.有点类似于异步的Ajax请求. 当调用某个耗时的方法时,可以不急于立刻获取结果,而是让被调用者立刻返回一个契约,并且将耗时的任务放到另外的线程执行.后续在凭契约来获取结果.

不愿言弃-念何的博客 607

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

高并发编程之生产者—消费者设计模式

一、生产者—消费者模式介绍 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。 二、为什么要使用生产者和消费者模...

weixin_42146366的博客 6938

生产者-消费者设计模式

一、生产者消费者设计模式 1、中间队列 一段内存空间,且可存取; 2、两种角色 (1)生产者:生产数据; (2)消费者:消费数据。 3、三种关系 (1)生产者与生产者的互斥关系; (2)消费者与消费者的互斥关系; (3)生产者与消费者的互斥且同步关系。 二、实现方式 1、使用synchronized(wait()和notify()) 2、使用Lock实现(await()和signal()) 3、阻...

qq_29224201的博客 1337

python设计模式之工厂模式、策略模式、生产者-消费者模式

前言这篇主要总结下 设计模式: 工厂模式、策略模式、生产者-消费者模式, 用python举例说明一、策略模式1.1 理论理解顾名思义,根据情况来选择不一样的《策略》。这种设计模式主要适用于: 希望能够根据特定条件选择方法的情况。 想根据具体场景理解可以看:https://cloud.tencent.com/developer/article/1774687 , 简而言之,根据不同的算法选择,来调用...

AI蜗牛车 502

【设计模式】java生产者和消费者的代码实例

生产者和消费者设计模式代码实例: 产品库和get/set方法: class SyncStack { int index = 0; WoTou[] wt = new WoTou[5]; public synchronized void push(WoTou w) { while(index

汤雨飞的专栏 735

设计模式-生产者消费者模式

设计模式-生产者消费者模式(java)生产者消费者模式:生成者消费者模式是指通过俩个不同的任务线程完成其相应的功能,二者公用一个公有队列,生产者进行产品的生成,而消费者负责消耗产品,当生产的产品大于公有队列的大小的时候,对生产者进行阻塞,当消费者消耗了以后,队列有了空间的时候,生产者在进行生产。这样一直循环的生产,消费的模型叫做生产者与消费者模式(个人理解)(以下代码使用Kotlin编写)packa

钢铁烈阳--非花非雾 812

设计模式三:生产者消费者模式

java设计模式之生产者/消费者模式 什么是生产者/消费者模式? 某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。结构图如下: ...

songzi1228的博客 1079

设计模式之生产者消费者模式

本文通过`wait()`和`notify()`方法,实现和分析消费者和生产者模式,此模式优雅的实现了生产者和消费者的解耦,并且支持并发。通过手写一份生产者消费者模式的代码,进行讲解。学习领悟了这种设计模式,才可以真正理解`消息中间件`实现的底层思想,比如Kafka、RocketMQ、RabbitMQ等。

五道口 2866

Java多线程 手写生产者消费者设计模式

文章目录为什么使用生产者和消费者模式什么是生产者消费者模式用wait和notify 实现 生产者消费者设计模式 为什么使用生产者和消费者模式 生产者用于生产数据, 消费者用于消费数据. 可能出现的情况是生产者生产的数据过慢,导致了消费者一直等待. 也可能消费者消费的过慢, 让生产者一直等待去生产. 于是就诞生了生产者 消费者模式, 让生产者和消费者进行解耦 . 可以得到更加顺畅的配合. 什么是生产者消费者模式 生产者消费者 会利用一个容器 . 一旦生产者生产了产品, 就会通知消费者去消费产品. 一旦消费者

Java持续实践 802

设计模式 保护性暂停/解耦等待/生产者消费者

设计模式-保护性暂停 实现原理: 因为线程各类数据都在栈中,而对象数据都在堆中所以可以实现两个线程在同一个对象代码块里面操作(临界区)。一个设置,一个拿取出。在setThread还未将数据写入时,getThread进行wait操作直到setThread进行notifuall操作时getThread才能拿到对象运行。 class GuardedObject{ private Object ...

qq_42411214的博客 1072
上一篇: 远程连接阿里云的redis
下一篇: SpringBoot+IDEA实现热部署
章 鱼
博客等级 码龄10年 203粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值