生产者消费者模式及简单的运用场景

article/2025/9/29 8:17:25

先考虑一个问题:服务端接受多个客户端提交的视频文件进行转码的操作,应该怎么设计?

由于转码比较花费时间,所以我们排除同步的想法。而转码需要用到的外部软件(exe文件),不能同时被多个线程用到,所以我们排除为每一个客户端提交新建一个线程进行转码的想法。

于是我们想到了静态加锁和队列。静态加锁有个缺点,稍后再提。当我们选择了队列,就选择了生产者消费者模式。

 

其流程图:

 

有流程图我们可以知道,生产者不关心数据什么时候被处理,消费者不关心数据什么时候产生,实现了解耦,也解决了阻塞。

 

还有一个比较典型的例子便是日志的记录,多线程产生日志,但写日志由于文件独占,不能多线程来写,于是我们就可以把线程压入队列,由日志线程来读取队列数据,完成写日志的操作。下面是一个简单的实现:

public class Log
{private static ConcurrentQueue<LogMessage> msgs = new ConcurrentQueue<LogMessage>();public static void WriteLog(string msg){msgs.Enqueue(new LogMessage(msg));}public static void Start(){Task.Factory.StartNew(() =>{while (true){while (msgs.TryDequeue(out LogMessage msg)){using (StreamWriter sw = new StreamWriter(msg.LogFile, true)){sw.WriteLine(msg.Message);}}Thread.Sleep(1000);}});}
}

这个是写日志的类

class LogMessage
{public string Message { get; set; }public string LogFile { get; set; }public LogMessage(string msg){this.Message = $"{DateTime.Now.ToString("HH:mm:ss ")} {msg}";string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log", DateTime.Now.ToString("yyyy-MM"));if (!Directory.Exists(path))Directory.CreateDirectory(path);this.LogFile = Path.Combine(path, DateTime.Now.ToString("dd") + ".log");}
}

这个是日志结构。包括产生日志的时间和写日志的日志文件。可以实现23:59产生的日志写到当天的文件夹中。

日志工具类的调用也非常简单,直接调用静态方法WriteLog就行。

 

回到开头所说加锁的弊端:线程排队并不是在队列中,没有先后顺序的保证,牵扯到严格顺序时就会有问题,比如写日志,socket数据接受等。

 

模式的应用场景:处理数据比较消耗时间,线程独占,生产数据不需要即时的反馈等。

 

例子的不足:

1.省略掉了缓冲区,使得生产者和消费者并不是完全解绑。改进:用一个独立的数据结构来放置数据,可以是缓存、文件、数据库,实现仅依赖于数据格式的解绑。

2.程序结束时,我们不能保证缓冲区数据是否全部处理完。改进:生产日志时,写文件/数据库,处理数据后,对处理过的数据进行标记,程序异常结束也没问题,下次重启先加载未处理数据,再一次展现单纯加锁的弊端。

转载于:https://www.cnblogs.com/blogXy/p/7755946.html


http://chatgpt.dhexx.cn/article/HLmfQaKG.shtml

相关文章

Java多线程系列—生产者消费者模式的多种实现(04)

生产者消费者模式 我们先来看看什么是生产者消费者模式,生产者消费者模式是程序设计中非常常见的一种设计模式,被广泛运用在解耦、消息队列等场景。 在现实世界中,我们把生产商品的一方称为生产者,把消费商品的一方称为消费者,有时生产者的生产速度特别快,但消费者的消…

生产者消费者模式的Java实现

一.概述 1. 什么是“生产者消费者模式”&#xff1f; 生产线程负责生产&#xff0c;消费线程负责消费 生产线程和消费线程要达到均衡。 生产满了就不能继续生产了&#xff0c;必须让消费线程进行消费 消费完了就不能再消费了&#xff0c;必须让生产线程进行生产 这是一种特殊的…

实现生产者消费者模式的三种方式

什么是生产者消费者模式 简单来说&#xff0c;生产者消费者模式就是缓冲区。 那么这么做有两个好处&#xff0c;一个是解耦&#xff0c;第二个是平衡生产能力和消费能力的差&#xff0c;因为生产者和消费者的速度是不一样的&#xff0c;有了这个缓冲区就可以平衡这样一个落差&…

生产者消费者模式最佳实践

测试环境&#xff1a;ubuntu18.04opencv4.2Qt 一个生产者-消费者模式下的视频处理框架。基础结构&#xff1a;视频读取类线程不断读取视频帧&#xff0c;处理类线程对图像进行处理&#xff0c;之后通过信号与槽机制在主线程中显示。特点&#xff1a;视频读取、处理为独立线程&a…

生产者、消费者模式

架构设计&#xff1a;生产者/消费者模式[0]&#xff1a;概述 今天打算来介绍一下“生产者&#xff0f;消费者模式”&#xff0c;这玩意儿在很多开发领域都能派上用场。由于该模式很重要&#xff0c;打算分几个帖子来介绍。今天这个帖子先来扫盲一 把。如果你对这个模式已经比较…

生产者和消费者模式详解

★简介 生产者消费者模式并不是GOF提出的23种设计模式之一&#xff0c;23种设计模式都是建立在面向对象的基础之上的&#xff0c;但其实面向过程的编程中也有很多高效的编程模式&#xff0c;生产者消费者模式便是其中之一&#xff0c;它是我们编程过程中最常用的一种设计模式。…

生产者消费者模式+代码实现

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 为什么要使用生产者和消费者模式 在线程世界里&#xff0c;生产者就是生产数据的线程&#xff0c;消费者就是消费数据的线程。在…

生产者消费者模式详解(转载)

★简介 在实际的软件开发过程中&#xff0c;经常会碰到如下场景&#xff1a;某个模块负责产生数据&#xff0c;这些数据由另一个模块来负责处理&#xff08;此处的模块是广义的&#xff0c;可以是类、函数、线程、进程等&#xff09;。产生数据的模块&#xff0c;就形象地称为生…

多线程之生产者消费者模式

文章目录 基本组成阻塞队列有界队列与无界队列ArrayBlockingQueueLinkedBlockingQueueSynchronousQueue 流量控制与信号量(Semaphore)双缓冲与Exchanger 基本组成 生产者&#xff1a;生产者的任务是生产产品&#xff0c;产品可以是数据&#xff0c;也可以是任务。(将产品存入传…

java 生产者消费者模式

java的生产者消费者模式&#xff0c;有三个部分组成&#xff0c;一个是生产者&#xff0c;一个是消费者&#xff0c;一个是缓存。 这么做有什么好处呢&#xff1f; 1.解耦(去依赖)&#xff0c;如果是消费者直接调用生产者&#xff0c;那如果生产者的代码变动了&#xff0c;消费…

生产者消费者模式浅析

由于最近工作中&#xff0c;涉及到生产者消费者设计模式&#xff0c;对此有一些体会&#xff0c;所以总结一下&#xff0c;与大家分享。 什么是生产者消费者模式 在工作中&#xff0c;大家可能会碰到这样一种情况&#xff1a;某个模块负责产生数据&#xff0c;这些数据由另一个…

java实现生产者消费者模式

一: 什么是生产者消费者模型 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯&#xff0c;而通过阻塞队列来进行通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔给阻塞队列&#xff0c;消费…

【Java】生产者消费者模式的实现

前言 生产者消费者问题是线程模型中的经典问题&#xff1a;生产者和消费者在同一时间段内共用同一存储空间&#xff0c;生产者向空间里生产数据&#xff0c;而消费者取走数据。 阻塞队列就相当于一个缓冲区&#xff0c;平衡了生产者和消费者的处理能力。这个阻塞队列就是用来…

生产者/消费者模式

[0]&#xff1a;概述 今天打算来介绍一下“生产者&#xff0f;消费者模式”&#xff0c;这玩意儿在很多开发领域都能派上用场。由于该模式很重要&#xff0c;打算分几个帖子来介绍。今天这个帖子先来扫盲一把。如果你对这个模式已经比较了解&#xff0c;请跳过本扫盲帖&#x…

(四)生产者消费者模式

&#xff08;一)生产者消费者模式原理&#xff1a; 在一个系统中&#xff0c;存在生产者和消费者两种角色&#xff0c;他们通过内存缓冲区进行通信&#xff0c;生产者生产消费者需要的资料&#xff0c;消费者把资料做成产品。生产消费者模式如下图&#xff1a; &#xff08;二…

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

一、什么是生产者-消费者模型 1、简单理解生产者-消费者模型 假设有两个进程&#xff08;或线程&#xff09;A、B和一个固定大小的缓冲区&#xff0c;A进程生产数据放入缓冲区&#xff0c;B进程从缓冲区中取出数据进行计算&#xff0c;这就是一个简单的生产者-消费者模型。这里…

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

1 基本概括 2 主要介绍 2.1 概念 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯&#xff0c;而通过阻塞队列来进行通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔给阻塞队列&#xff…

生产者消费者模式三种实现方式

目录 1.什么是生产者消费者模式&#xff1a;2.生产者消费者模型的实现&#xff1a;第一种&#xff1a;使用 synchronized和wait、notify第二种&#xff1a;使用 Lock和await、signal第三种&#xff1a;使用 阻塞队列 BlockingQueue 1.什么是生产者消费者模式&#xff1a; 生产…

t-SNE算法

t-SNE(t-distributed stochastic neighbor embedding)是用于降维的一种机器学习算法&#xff0c;是由 Laurens van der Maaten 和 Geoffrey Hinton在 08 年提出来。t-SNE 是一种非线性降维算法&#xff0c;非常适用于高维数据降维到 2 维或者 3 维&#xff0c;进行可视化。在实…

t-SNE概述

为了循序渐进, 先来学习SNE. SNE 无论是多维数据还是词向量, 都是一个个散落在空间中的点, 点与点之间距离近的, 就可以看作属于同一分类或近义词. 衡量两点距离有很多种手段, 但最常用的还是欧式距离, 所以欧氏距离与相似度的关系可以用某种公式近似表达, 这样就可以把空间信…