我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#使用泛型队列Queue实现生产消费模式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#使用泛型队列Queue实现生产消费模式

如果把生产消费想像成自动流水生产线的话,生产就是流水线的物料,消费就是某种设备对物料进行加工的行为,流水线就是队列。

现在,要写一个体现生产消费模式的泛型帮助类,比如叫ProducerConsumer<T>。

该类肯定会维护一个有关生产、物料的Queue<T>类型的字段,还存在一个有关消费、Action<T>类型的字段。

在ProducerConsumer类的构造函数中,为Action<T>类型的字段赋值,并开启后台有关消费的线程。

ProducerConsumer类肯定存在一个进队列的方法,并且要保证在多线程情况下,同一时间只有一个生产或物料进入队列。

ProducerConsumer类还存在一个有关消费的方法,并且保证在多线程情况下,同一时间只有一个生产或物料出列,并消费它。

另外,在生产或物料在出队列的时候,可能会出现队列中暂时没有生产或物料的情况,这时候我们希望线程阻塞一下,这需要通过AutoResetEvent实现。AutoResetEvent的大致原理是:当生产或物料进入队列的时候需要告诉AutoResetEvent一下,当队列中暂时没有生产或物料的时候,也需要告诉AutoResetEvent,让它来阻塞线程。

  //有关生产消费的泛型类
    public class ProducerConsumer<T>
    {
        //用来存储生产者的队列
        private readonly Queue<T>  queue = new Queue<T>();
        //锁
        private readonly object queueLocker = new object();
        //消费行为
        private readonly Action<T> consumerAction;
        //出列的时候需要检查队列中是否有元素,如果没有,需要阻塞
        private readonly AutoResetEvent queueWaitHandle = new AutoResetEvent(false);
        public ProducerConsumer(Action<T> consumerAction)
        {
            if (consumerAction == null)
            {
                throw new ArgumentNullException("consumerAction");
            }
            this.consumerAction = consumerAction;
            //后台开启一个线程开始消费生产者
            new Thread(this.ConsumeItems){IsBackground = true}.Start();
        }
        //进列
        public void Enqueue(T item)
        {
            //确保同一时间只有一个生产者进列
            lock (queueLocker)
            {
                queue.Enqueue(item);
                //每次进列都要设置AutoResetEvent事件
                this.queueWaitHandle.Set();
            }
        }
        //消费动作
        private void ConsumeItems()
        {
            while (true)
            {
                T nextItem = default(T);
                //标志,确认队列中的生产者是否存在
                bool doesItemExist;
                //确保同一时间只有一个生产者出列
                lock (this.queueLocker)
                {
                    //先确认队列中的生产者是否存在
                    doesItemExist = this.queue.Count > 0;
                    if (doesItemExist)
                    {
                        nextItem = this.queue.Dequeue();
                    }
                    
                }
                //如果生产者存在,才消费生产者
                if (doesItemExist)
                {
                    this.consumerAction(nextItem);
                }
                else//否则的话,再等等下一个队列中的生产者
                {
                    this.queueWaitHandle.WaitOne();
                }
                
            }
        }
    }

客户端,针对多线程情形。

    class Program
    {
        static void Main(string[] args)
        {
            //实例化一个int类型的生产消费实例
            var producerConsumer = new ProducerConsumer<int>(i => Console.WriteLine("正在消费" + i));
            Random random = new Random();
            //开启进队列线程
            var t1 = new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    producerConsumer.Enqueue(i);
                    Thread.Sleep(random.Next(0,5));
                }
            });
            var t2 = new Thread(() =>
            {
                for (int i = 0; i > -100; i--)
                {
                    producerConsumer.Enqueue(i);
                    Thread.Sleep(random.Next(0, 5));
                }
            });
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
            Thread.Sleep(50);
            Console.ReadKey();
        }
    }

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对编程网的支持。如果你想了解更多相关内容请查看下面相关链接

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#使用泛型队列Queue实现生产消费模式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#使用泛型队列Queue实现生产消费模式

这篇文章介绍了C#使用泛型队列Queue实现生产消费模式的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-11-13

Queue 实现生产者消费者模型(实例讲解)

Python中,队列是线程间最常用的交换数据的形式。 Python Queue模块有三种队列及构造函数: 1、Python Queue模块的FIFO队列先进先出。 class Queue.Queue(maxsize) 2、LIFO类似于堆,
2022-06-04

C++实现简单的生产者-消费者队列详解

这篇文章主要为大家详细介绍了如何利用C++实现一个简单的生产者-消费者队列,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
2023-05-18

Java多线程Queue、BlockingQueue和使用BlockingQueue实现生产消费者模型方法解析

Queue是什么队列,是一种数据结构。除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的。无论使用哪种排序方式,队列的头都是调用remove()或poll()移除元素的。在FIFO队列中,所有新元素都插
2023-05-30

队列的生产者与消费者模式在PHP与MySQL中的实现方法

随着互联网业务的快速发展,系统中处理大量任务的需求变得越来越迫切。队列是一种常见的解决方案,可以高效地处理任务。队列的生产者-消费者模式(Producer-Consumer Pattern)在PHP和MySQL中的实现方法是一种常见的解决方
2023-10-21

怎么在Python中利用 Asyncio模块实现一个生产消费者模型

本文章向大家介绍怎么在Python中利用 Asyncio模块实现一个生产消费者模型的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究
2023-06-06

Python中怎么利用多线程实现生产者消费者模式

Python中怎么利用多线程实现生产者消费者模式,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。什么是生产者消费者模式在软件开发的过程中,经常碰到这样的场景:某些模块负责生产数据
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录