Creating a blocking Queue<T> in .NET

这里的代码来自我们的StackOverflow 中的代码示例,我添加了一些中文注释;

 //there I will create blocking quene;class SizeQueue<T>{private readonly Queue<T> queue = new Queue<T>();private readonly int _maxSize;private readonly object _locker = new object();private static bool closing;public SizeQueue(int size){this._maxSize = size;}public void Enquen(T item){lock (_locker){//这里要重点理解使用while 而不是 我们的if//应为当另外一个线程Pulse 之后,又可能另外一个线程获得锁,而不是当前等待的线程;while (this._maxSize <= this.queue.Count)  //为什么这里要用while 而不是if呢;  应为当 pulse 之后释放锁,很有可能另外一个线程活到锁; 然后进入到队列,添加,出来之后返现,队列还是慢慢的;
                {Monitor.Wait(_locker); //进入等待队列;
                }//否则就进入我们的 队列中;
                queue.Enqueue(item);Monitor.PulseAll(_locker); // wake up any blocked dequeue 同时所有的线程去争夺锁,然后 取出数据;
}}public T Eequeue(){lock (_locker){while (queue.Count == 0){Monitor.Wait(queue);}T item = queue.Dequeue();if (queue.Count == _maxSize - 1) //队列装满了之后,
                {// wake up any blocked enqueueMonitor.PulseAll(queue); //通知线程继续写入;
                }return item;}}//empty queue just returns(rather than blocking)://锁,独占锁,确保一次只有一个线程能够操作我们的队列;//特别是在我们的读写的时候//读的时候,不允许写//写的时候,不允许读;//这里我们添加一个close 和 tryDequeue的方法;public void Close(){lock (_locker){closing = true;Monitor.PulseAll(_locker);}}/// <summary>/// 考虑到有关系的情况;/// </summary>/// <param name="value"></param>/// <returns></returns>public bool TryDequeue(out T value){lock (_locker){while (queue.Count == 0){if (closing){value = default(T);return false;}Monitor.Wait(_locker);}value = value = queue.Dequeue();if (queue.Count == this._maxSize - 1){Monitor.PulseAll(_locker);}return true;}}}

当然这里还有我们的第二个版本的使用;

    class BlockingQueue<T>{/// <summary>///队列最大值/// </summary>private readonly int _maxSize;/// <summary>/// 我们的队列/// </summary>private Queue<T> _Queue = new Queue<T>();/// <summary>/// 我们的独占锁/// </summary>private readonly object _locker = new object();/// <summary>/// 是否停止操作;/// </summary>private bool _Quit = false;/// <summary>/// 初始化队列的大小;/// </summary>public BlockingQueue(int maxSize){this._maxSize = maxSize;}/// <summary>/// 取消操作/// </summary>public void Quit(){lock (_locker){_Quit = true;Monitor.PulseAll(_locker);}}/// <summary>/// 队列的进入;/// </summary>/// <param name="t"></param>public bool Enqueue(T t){lock (_locker) //确保线程的安全;
            {while (!this._Quit && this._Queue.Count >= this._maxSize) Monitor.Wait(_locker); //进入等待的队列中;if (_Quit) return false;//进入队列
                _Queue.Enqueue(t);//释放信号;Monitor.PulseAll(_locker);  //一旦队列中有了,就通知 去去;
}return true;}/// <summary>///取出队列中的值;/// </summary>/// <param name="t"></param>/// <returns></returns>public bool Dequeue(out T t){t = default(T);lock (_locker){while (!this._Quit && this._Queue.Count == 0) Monitor.Wait(_locker);if (_Queue.Count == 0) return false;  //这个大概是以多余的安全机制吧;
t = this._Queue.Dequeue();Monitor.PulseAll(_locker);}return true;}//整体来说,这个方法还挺好使用使用的,效果不错的感觉;//线程的执行是没有太多额顺序的的; 如果三个线程读,两个线程写; 可能window 线程如何去协调这些线程执行呢;
}class Program{//with one fast producer and two slow consumers:static void Test(){var q = new BlockingQueue<int>(4);//一个线程生成;new Thread(() =>{for (int x = 0; ; x++){if (!q.Enqueue(x)) break;Trace.WriteLine(x.ToString("0000") + " >");}Trace.WriteLine("Producer quitting");}).Start();//消费者;// Consumersfor (int i = 0; i < 2; i++){new Thread(() =>{for (;;){Thread.Sleep(100);int x = 0;if (!q.Dequeue(out x)) break;Trace.WriteLine("     < " + x.ToString("0000"));}Trace.WriteLine("Consumer quitting");}).Start();}Thread.Sleep(3000);Trace.WriteLine("Quitting");q.Quit();}static void Main(string[] args){Test();}}

要锻炼自己写源代码的能力,所以要多看,多学习,看多额,才能写点东西出来的呀;

这样的效果还是挺好;

转载于:https://www.cnblogs.com/mc67/p/7569004.html

Creating a blocking QueueT in .NET相关推荐

  1. 使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with

    使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with ...

  2. 用Unity和Playmaker创建一个限时游戏 Creating a Time Limit game with Unity and Playmaker

    本课程结束时,您将拥有在Unity中使用Playmaker创建游戏的工具 你会学到: playmaker状态的基础以及它们如何与动作一起工作. 安装悬停车,可以在竞技场内行驶. 不同力度的射击地雷驱动 ...

  3. Blender模块化建筑环境地形场景制作视频教程 Creating modular environments

    Blender模块化建筑环境地形场景制作视频教程 Creating modular environments Blender模块化建筑环境地形场景制作视频教程 Creating modular env ...

  4. 关于Blocking IO, Non-Blocking IO 和 Asynchronous I/O的理解

    文章写得很详细很清楚了,对我的理解帮助很大. 转载自:http://www.cnblogs.com/whyandinside/archive/2012/03/04/2379234.html. 概括来说 ...

  5. Error Creating Control when creating a custom control

    如果你在创建ASP.NET的Server Control 是遇到报错: "Error Creating Control" when creating a custom contro ...

  6. org.springframework.beans.factory.BeanCreationException: Error creating bean with name

    严重: Exception sending context initialized event to listener instance of class org.springframework.we ...

  7. Error creating bean with name 'org.springframework.amqp.rabbit.config.ListenerContainerFactoryBean#0

    Spring 整合rabbitmq 出现错误 严重: Exception sending context initialized event to listener instance of class ...

  8. 图像拼接--Creating full view panoramic image mosaics and environment maps

    Creating Full View Panoramic Image Mosaics and Environment Maps In ACM SIGGRAPH, pages 251–258, 1997 ...

  9. Error creating bean with name 'multipleEntityManagerFactory' defined in class

    2019独角兽企业重金招聘Python工程师标准>>> Error creating bean with name 'multipleEntityManagerFactory' de ...

最新文章

  1. [51单片机学习笔记ONE]-----LED灯的多种使用方法
  2. qt 搜索隐藏文件_MacOS如何搜索隐藏文件?MacOS搜索隐藏文件的方法
  3. HDU 4652 Dice:期望dp(成环)【错位相减】
  4. 站长常用广告代码的表达大全
  5. lisp 焊接符号标注_焊接符号标注大全
  6. 关于 Redis 的一些新特性、使用建议和最佳实践
  7. Boost:基于Boost的阻塞udp echo的测试程序
  8. 准备写个delphi 代码生成器或者说是一个记事本
  9. java 控制jsp_JSP学习之Java Web中的安全控制实例详解
  10. python变量和常量_Python数学模块常量和示例
  11. eclipse远程连接hadoop_hadoop集群搭建详细方法
  12. oracle 序列_Oracle好记性不如烂笔头序列及日期时间的插入
  13. 在c语言中输入三个数据类型,【C语言讲解】第二章:数据类型3
  14. 3. 密切与企业的合作,构建“产学合作”教育模式
  15. excel poi 实现图片导出
  16. html外链自动加nofollow,WordPress自动为站外链接添加nofollow标签
  17. 计算机硬盘问题要求备份在弄,硬盘驱动器故障解决方案
  18. 汉诺塔,简单递归带你破解出攻略
  19. 推荐:几个优质的数据公众号
  20. 网页报404解决办法

热门文章

  1. Android tv开发px,【Android】TV端项目开发挖坑总结
  2. java报505_Java调用URL错误,报505
  3. double四舍五入
  4. RestTemplate与Feign使用对比
  5. 怎样在matlab q-q图上读出斜率,Q分解法潮流计算matlab小程序
  6. .class与.java_Java中Class类的作用与深入理解
  7. 启动的时候闪退_APP突然闪退怎么办?学会这五个妙招比换手机实用,看完望周知...
  8. 重学前端学习笔记(十三)--浏览器工作解析(三)
  9. windows知识点2
  10. linux driver开发