博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Creating a blocking Queue<T> in .NET
阅读量:4676 次
发布时间:2019-06-09

本文共 5796 字,大约阅读时间需要 19 分钟。

Creating a blocking Queue<T> in .NET

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

//there I will create blocking quene;    class SizeQueue
{ private readonly Queue
queue = new Queue
(); 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 enqueue Monitor.PulseAll(queue); //通知线程继续写入; } return item; } } //empty queue just returns(rather than blocking): //锁,独占锁,确保一次只有一个线程能够操作我们的队列; //特别是在我们的读写的时候 //读的时候,不允许写 //写的时候,不允许读; //这里我们添加一个close 和 tryDequeue的方法; public void Close() { lock (_locker) { closing = true; Monitor.PulseAll(_locker); } } ///
/// 考虑到有关系的情况; /// ///
///
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
{ ///
///队列最大值 /// private readonly int _maxSize; ///
/// 我们的队列 /// private Queue
_Queue = new Queue
(); ///
/// 我们的独占锁 /// private readonly object _locker = new object(); ///
/// 是否停止操作; /// private bool _Quit = false; ///
/// 初始化队列的大小; /// public BlockingQueue(int maxSize) { this._maxSize = maxSize; } ///
/// 取消操作 /// public void Quit() { lock (_locker) { _Quit = true; Monitor.PulseAll(_locker); } } ///
/// 队列的进入; /// ///
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; } ///
///取出队列中的值; /// ///
///
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
(4); //一个线程生成; new Thread(() => { for (int x = 0; ; x++) { if (!q.Enqueue(x)) break; Trace.WriteLine(x.ToString("0000") + " >"); } Trace.WriteLine("Producer quitting"); }).Start(); //消费者; // Consumers for (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

你可能感兴趣的文章
poj 2236(并查集的应用)
查看>>
C 栈 链式存储
查看>>
Java 游戏报错 看不懂求教
查看>>
APP自动化测试
查看>>
HTML中让表单input等文本框为只读不可编辑的方法
查看>>
nodejs做中间层,向后端取数据
查看>>
IntelliJ IDEA 2017 MySQL5 绿色版 Spring 4 Mybatis 3 配置步骤详解(二)
查看>>
(转)Java DecimalFormat 用法(数字格式化)
查看>>
hiho_100_八数码
查看>>
Eclipse序列号生成代码
查看>>
JVM
查看>>
设计模式记录
查看>>
SPF,DSPF,RDPF,SPEF and SBPF.
查看>>
JS学习文章
查看>>
window系统服务器,远程连接mysql数据库。
查看>>
CAS总结之Ticket篇
查看>>
Python2.7升级至Python3.6
查看>>
框架集
查看>>
003
查看>>
HDU 2923 Einbahnstrasse (最短路,3级)
查看>>