Creating a blocking QueueT in .NET
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相关推荐
- 使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with
使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with ...
- 用Unity和Playmaker创建一个限时游戏 Creating a Time Limit game with Unity and Playmaker
本课程结束时,您将拥有在Unity中使用Playmaker创建游戏的工具 你会学到: playmaker状态的基础以及它们如何与动作一起工作. 安装悬停车,可以在竞技场内行驶. 不同力度的射击地雷驱动 ...
- Blender模块化建筑环境地形场景制作视频教程 Creating modular environments
Blender模块化建筑环境地形场景制作视频教程 Creating modular environments Blender模块化建筑环境地形场景制作视频教程 Creating modular env ...
- 关于Blocking IO, Non-Blocking IO 和 Asynchronous I/O的理解
文章写得很详细很清楚了,对我的理解帮助很大. 转载自:http://www.cnblogs.com/whyandinside/archive/2012/03/04/2379234.html. 概括来说 ...
- Error Creating Control when creating a custom control
如果你在创建ASP.NET的Server Control 是遇到报错: "Error Creating Control" when creating a custom contro ...
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name
严重: Exception sending context initialized event to listener instance of class org.springframework.we ...
- Error creating bean with name 'org.springframework.amqp.rabbit.config.ListenerContainerFactoryBean#0
Spring 整合rabbitmq 出现错误 严重: Exception sending context initialized event to listener instance of class ...
- 图像拼接--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 ...
- Error creating bean with name 'multipleEntityManagerFactory' defined in class
2019独角兽企业重金招聘Python工程师标准>>> Error creating bean with name 'multipleEntityManagerFactory' de ...
最新文章
- [51单片机学习笔记ONE]-----LED灯的多种使用方法
- qt 搜索隐藏文件_MacOS如何搜索隐藏文件?MacOS搜索隐藏文件的方法
- HDU 4652 Dice:期望dp(成环)【错位相减】
- 站长常用广告代码的表达大全
- lisp 焊接符号标注_焊接符号标注大全
- 关于 Redis 的一些新特性、使用建议和最佳实践
- Boost:基于Boost的阻塞udp echo的测试程序
- 准备写个delphi 代码生成器或者说是一个记事本
- java 控制jsp_JSP学习之Java Web中的安全控制实例详解
- python变量和常量_Python数学模块常量和示例
- eclipse远程连接hadoop_hadoop集群搭建详细方法
- oracle 序列_Oracle好记性不如烂笔头序列及日期时间的插入
- 在c语言中输入三个数据类型,【C语言讲解】第二章:数据类型3
- 3. 密切与企业的合作,构建“产学合作”教育模式
- excel poi 实现图片导出
- html外链自动加nofollow,WordPress自动为站外链接添加nofollow标签
- 计算机硬盘问题要求备份在弄,硬盘驱动器故障解决方案
- 汉诺塔,简单递归带你破解出攻略
- 推荐:几个优质的数据公众号
- 网页报404解决办法
热门文章
- Android tv开发px,【Android】TV端项目开发挖坑总结
- java报505_Java调用URL错误,报505
- double四舍五入
- RestTemplate与Feign使用对比
- 怎样在matlab q-q图上读出斜率,Q分解法潮流计算matlab小程序
- .class与.java_Java中Class类的作用与深入理解
- 启动的时候闪退_APP突然闪退怎么办?学会这五个妙招比换手机实用,看完望周知...
- 重学前端学习笔记(十三)--浏览器工作解析(三)
- windows知识点2
- linux driver开发