转载至 https://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified

  1. /*
  2. * 这是一个完整源代码示例,演示了此模式的多功能性。它实现了一个可以停止的阻塞队列。
  3. * 阻塞队列是固定大小的队列。如果队列已满,则尝试添加项目将被阻止。
  4. * 如果队列为空,则尝试删除项目将阻止。
  5. * 当Quit()被调用时,队列停止。这意味着您无法再添加任何项目,但可以删除现有项目,直到队列为空。此时,队列已完成。
  6. * 这是一组非常复杂的条件。您可以使用更高级别的结构组合来实现它,但它会更难。该模式使得该实现相对简单。
  7. *
  8. */
  9. using System;
  10. using System.Threading;
  11. using System.Collections.Generic;
  12.  
  13. namespace TestBlockQueue
  14. {
  15. public class BlockingQueue<T>
  16. {
  17. readonly int _Size = ;
  18. readonly Queue<T> _Queue = new Queue<T>();
  19. readonly object _Key = new object();
  20. bool _Quit = false;
  21.  
  22. public BlockingQueue(int size)
  23. {
  24. _Size = size;
  25. }
  26.  
  27. public void Quit()
  28. {
  29. lock (_Key)
  30. {
  31. _Quit = true;
  32.  
  33. Monitor.PulseAll(_Key);
  34. }
  35. }
  36.  
  37. public bool Enqueue(T t)
  38. {
  39. lock (_Key)
  40. {
  41. while (!_Quit && _Queue.Count >= _Size) Monitor.Wait(_Key);
  42.  
  43. if (_Quit) return false;
  44.  
  45. _Queue.Enqueue(t);
  46.  
  47. Monitor.PulseAll(_Key);
  48. }
  49.  
  50. return true;
  51. }
  52.  
  53. public bool Dequeue(out T t)
  54. {
  55. t = default(T);
  56.  
  57. lock (_Key)
  58. {
  59. while (!_Quit && _Queue.Count == ) Monitor.Wait(_Key);
  60.  
  61. if (_Queue.Count == ) return false;
  62.  
  63. t = _Queue.Dequeue();
  64.  
  65. Monitor.PulseAll(_Key);
  66. }
  67.  
  68. return true;
  69. }
  70. }
  71.  
  72. /// <summary>
  73. /// 对于任意数量的生产者和消费者的并发访问,此实现是安全的。以下是一个快速生产者和两个慢速消费者的示例
  74. /// </summary>
  75. public class Program
  76. {
  77. public static void Main(string[] args)
  78. {
  79. var q = new BlockingQueue<int>();
  80.  
  81. // Producer
  82. new Thread(() =>
  83. {
  84. for (int x = ; ; x++)
  85. {
  86. if (!q.Enqueue(x)) break;
  87. Console.WriteLine(x.ToString("") + " >");
  88. }
  89. Console.WriteLine("Producer quitting");
  90. }).Start();
  91.  
  92. // Consumers
  93. for (int i = ; i < ; i++)
  94. {
  95. new Thread(() =>
  96. {
  97. for (; ; )
  98. {
  99. Thread.Sleep();
  100. int x = ;
  101. if (!q.Dequeue(out x)) break;
  102. Console.WriteLine(" < " + x.ToString(""));
  103. }
  104. Console.WriteLine("Consumer quitting");
  105. }).Start();
  106. }
  107.  
  108. Thread.Sleep();
  109.  
  110. Console.WriteLine("Quitting");
  111.  
  112. q.Quit();
  113. }
  114. }
  115. }

Monitor 实现阻塞队列 + 生产消费者实例的更多相关文章

  1. 10 阻塞队列 & 生产者-消费者模式

    原文:http://www.cnblogs.com/dolphin0520/p/3932906.html 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(Li ...

  2. Day034--Python--锁, 信号量, 事件, 队列, 生产者消费者模型, joinableQueue

    进程同步: 1. 锁 (重点)    锁通常被用来实现对共享资源的同步访问.为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁, ...

  3. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))

    昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...

  4. 5 并发编程-(进程)-队列&生产者消费者模型

    1.队列的介绍 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的 创建队列的类(底层就是以管道和锁定的方式实现 ...

  5. Python——Queue模块以及生产消费者模型

    1.了解Queue Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递 |queue.Qu ...

  6. Java 并发系列之七:java 阻塞队列(7个)

    1. 基本概念 2. 实现原理 3. ArrayBlockingQueue 4. LinkedBlockingQueue 5. LinkedBlockingDeque 6. PriorityBlock ...

  7. Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Create ...

  8. 你真的知道.NET Framework中的阻塞队列BlockingCollection的妙用吗?

    BlockingCollection集合是一个拥有阻塞功能的集合,它就是完成了经典生产者消费者的算法功能.一般情况下,我们可以基于 生产者 - 消费者模式来实现并发.BlockingCollectio ...

  9. BlockingQueue 阻塞队列(生产/消费者队列)

    1:BlockingQueue的继承关系 java.util.concurrent 包里的 BlockingQueue是一个接口, 继承Queue接口,Queue接口继承 Collection Blo ...

随机推荐

  1. C++ 读取一个文件下所有文件的文件名

    Windows: #include<iostream> #include<string> #include <io.h> void readFileNameInDi ...

  2. golang内建容器

  3. PHP CLI中,三个系统常量:STDIN、STDOUT、STDERR

    PHP CLI中,有三个系统常量,分别是STDIN.STDOUT.STDERR,代表文件句柄. /** *@ 标准输入 *@ php://stdin & STDIN *@ STDIN是一个文件 ...

  4. Net core 2.x 升级 3.0 使用自带 System.Text.Json 时区 踩坑经历

    .Net Core 3.0 更新的东西很多,这里就不多做解释了,官方和博园大佬写得很详细 关于 Net Core 时区问题,在 2.1 版本的时候,因为用的是 Newtonsoft.Json,配置比较 ...

  5. System.Data.Entity.Core.EntityException: 可能由于暂时性失败引发了异常。如果您在连接到 SQL Azure 数据库,请考虑使用 SqlAzureExecutionStrategy。

    代码异常描述  ************** 异常文本 **************System.Data.Entity.Core.EntityException: 可能由于暂时性失败引发了异常.如果 ...

  6. IDEA中搭建Maven环境

    一.maven的作用 maven是一个构建项目的工具 从项目的创建(代码.配置文件.测试代码如何存放) --> 项目代码的编译 --> 测试 -->项目发布上线 做一整套约定和解决方 ...

  7. kubernetes第一章--介绍

  8. “http”和“https”的区别是什么?优缺点是什么?

    1. http 的URL 以http:// 开头,https以https:// 开头. 2. http 标准端口是80 ,https是443. 3.https 协议需要到ca申请证书,http不需要. ...

  9. JavaScript之变量

    var a; // 声明变量a,变量:值可以改变的,相当于数学x,y,z... a=10; // 将10赋值给a var test; var Test; /* 变量命名规则: 1.不能以数字开头 2. ...

  10. SAP Marketing Cloud功能简述(五) : 销售计划管理

    Grace前四篇介绍SAP Marketing Cloud的文章: SAP Marketing Cloud功能简述(一) : Contacts和Profiles SAP Marketing Cloud ...