// 多个生产者和多个消费者,能生产n个产品的情况using System; using System.Threading;public class HoldIntegerSynchronized{private int[] buffer; //缓冲区private int occupiedBufferCount = 0;private int readPosition = 0 , writePosition = 0;//下一个读到的位置和写到的位置public HoldIntegerSynchronized(int capacity){buffer = new int[capacity];}public int BufferSize{get{return buffer.Length;}}public int Buffer{get{int bufferCopy;// 加锁lock(this){while(occupiedBufferCount == 0){ //多个消费者,所以此处改用whileConsole.WriteLine(Thread.CurrentThread.Name + " tries to read. ");DisplayState("Buffer Empty. " + Thread.CurrentThread.Name + " waits.");Monitor.Wait(this); // 为临界区之外等待的生产者放行,让他来"生产"// 一直到生产者生产结束,调用了Monitor.PauseAll()// 才能继续执行下去,此时,消费者自动重新获得this的锁 }--occupiedBufferCount;bufferCopy = buffer[readPosition];readPosition = (readPosition + 1) % buffer.Length; DisplayState(Thread.CurrentThread.Name + " reads " + bufferCopy);// 通知,让等待的 生产者线程 进入Started状态,如果生产者处于临界区之外,这句话执行完后他仍然在临界区之外Monitor.PulseAll(this);// 释放锁}//lockreturn bufferCopy;}set{// 加锁lock(this){while(occupiedBufferCount == buffer.Length){Console.WriteLine(Thread.CurrentThread.Name + " tries to write. ");DisplayState("Buffer Full. " + Thread.CurrentThread.Name + " waits.");Monitor.Wait(this); // 为临界区之外等待消费者放行,让他来"消费"// 一直到消费者调用了Monitor.Pause()// 才能继续执行下去,此时,生产者自动重新获得this的锁 }buffer[writePosition] = value;++occupiedBufferCount; writePosition = (writePosition + 1) % buffer.Length;DisplayState(Thread.CurrentThread.Name + " writes " + value);// 通知,让Wait状态的 消费者 进入Started状态,如果消费者处于临界区之外,这句话执行完后他仍然在临界区之外Monitor.PulseAll(this);// 释放锁 }}}public void DisplayState(string operation){Console.Write("{0,-35}",operation);for(int i = 0; i < BufferSize; i++ ){int a = readPosition;int b = writePosition;if( a <= i && i < b) {Console.Write("{0,-9}",buffer[i]);}else if( b < a && !( b <= i && i < a ) ){Console.Write("{0,-9}",buffer[i]);}else if( occupiedBufferCount == BufferSize){Console.Write("{0,-9}",buffer[i]);}else{Console.Write("{0,-9}","");}}Console.WriteLine("{0}/r/n",occupiedBufferCount);} }class Producer{private HoldIntegerSynchronized sharedLocation;private Random randomSleepTime;public Producer(HoldIntegerSynchronized shared,Random random){sharedLocation = shared;randomSleepTime = random;}public void Produce(){for (int count=0; count<3; count++) {Thread.Sleep(randomSleepTime.Next(1,2000));sharedLocation.Buffer = randomSleepTime.Next(5,10);}Console.WriteLine(Thread.CurrentThread.Name + " done producing./r/nTerminating " + Thread.CurrentThread.Name + "./r/n");} }class Consumer{private HoldIntegerSynchronized sharedLocation;private Random randomSleepTime;public Consumer(HoldIntegerSynchronized shared,Random random){sharedLocation = shared;randomSleepTime = random;}public void Consume(){int sum = 0;for (int count=0; count<4; count++) {Thread.Sleep(randomSleepTime.Next(1,2000));sum += sharedLocation.Buffer;}Console.WriteLine(Thread.CurrentThread.Name + " read values totaling:" + sum + "/r/nTerminating " + Thread.CurrentThread.Name + ".");} }class SharedCell{static void Main(string[] args){HoldIntegerSynchronized holdInteger = new HoldIntegerSynchronized(5);Random random = new Random();Thread[] producerThreads = new Thread[4];Thread[] consumerThreads = new Thread[3];Console.Write("{0,-35}","Operation");for(int i = 0;i < holdInteger.BufferSize;i++){Console.Write("{0,-9}","Elem " + i);}Console.WriteLine("Occupied Count/r/n");for(int i = 0; i < producerThreads.Length;i++){Producer producer = new Producer(holdInteger,random);producerThreads[i] = new Thread(new ThreadStart(producer.Produce));producerThreads[i].Name = "Producer No." + i;}for(int i = 0; i < consumerThreads.Length;i++){Consumer consumer = new Consumer(holdInteger,random);consumerThreads[i] = new Thread(new ThreadStart(consumer.Consume));consumerThreads[i].Name = "Consumer No." + i;}for(int i = 0; i < producerThreads.Length;i++){producerThreads[i].Start();}for(int i = 0; i < consumerThreads.Length;i++){consumerThreads[i].Start();}} }
C#编写的多生产者多消费者同步问题
转载于:https://www.cnblogs.com/gc2013/p/3959384.html
相关文章:

展望2009,回眸2008
2008年真正的过去了,已经感觉不到2008年的存在。 2009年来了,似乎真正的来了。 生活的压力更大了,工作也不太顺利。 希望越来越好,也不知道是不是真的该跳槽了。 待在这里很郁闷。 转载于:https://www.cnblogs.com/tacker/archive…

m_Orchestrate learning system---七、如何快速学好前端
m_Orchestrate learning system---七、如何快速学好前端 一、总结 一句话总结:看视频啊,系统看视频啊 1、如何解决单词数字太长超出边界的问题? word-wrap 把编辑删除都挤跑了 2、amaze ui中a标签和button标签可以互换么? 其实弄上…

1062 Talent and Virtue
1.在结构体里面设置total_grades属性是明智之举,但是不可以在结构体内得到total_gradesvirtue_gradetalent_grade; 2.弄清题意,对人进行分类,等级越高type值越小,但是注意分的类别也许出现交叉的情况,细的要出现在粗的…

用百度直达号获取新用户 让顾客直达商家服务
直达号是什么? 直达号,商家在百度移动平台的官方服务账号。基于移动搜索、账号、地图、个性化推荐等多种方式,让顾客随时随地直达商家服务。 直达号其实就是两个功能: √ 提供一个手机网站模板,入住商家可以建自己的手机网站。…

【Quartz】实现接口封装化(二)
原文:【Quartz】实现接口封装化(二)前言 通过昨天的努力终于算是了解Quartz这个定时器的简单使用,为了更深一步的了解和基于以后希望在项目中能使用他。所有我对他做了一下简单的封装操作,便于以后从新建立新工作和触发器&#…

怎么成为优秀的软件模型设计者?
作者:Scott Ambler著,乐林峰 译 本文选自:www.umlchina.com 2002年03月25日 我们期待自己成为一个优秀的软件模型设计者,但是,要怎样做,又从哪里开始呢? 将下列原则应用到你的软件工程中&…

1012 The Best Rank
思路:读入全部的数据之后,按照四个cmp函数对数组进行排序,给每生的4个科目的排名赋值,读入要检验的id后使用strcmp对数组中的id进行遍历(幸好这里数组大小和要检验的数目乘积不超过4万),如果找到了相同id,调用写好的得…

SDWebImage使用——一个可管理远程图片加载的类库
SDWebImage托管在github上。https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片。具有缓存管理、异步下载、同一个URL下载次数控制和优化等特征。 将SDWebImage类库添加入工程时,一定注意需要添加MapKit.framework&…

EXECL使用技巧(转)
2007-03-18 09:07 一、求字符串中某字符出现的次数: 例:求A1单元格中字符"a"出现的次数: LEN(A1)-LEN(SUBSTITUTE(A1,"a","")) 二、如何在不同工作薄之间复制宏: 1、打开含有宏的工作薄,…

微信小程序(canvas)画图保存到本地相册(wepy)
html标签部分 因为这个需要用户授权 所以需要使用button,画布使用的是canvas,这个可以参考小程序官方文档,代码如下 <button classbtn type"default" open-type"getUserInfo" tapexportImg>生成图片保存到本地&l…

1016 Phone Bills
目录 概述: 一些小的注意点 AC代码 概述: 这道题是我迄今做出来的最复杂的一道PAT了,该题被归类到排序专题下,其实还涉及到大量的字符串处理等别的我暂时也说不出的知识点。 排序函数我写了两个,1是cmp࿰…
C# GDI+ 简单绘图 (三) 仿浏览器截屏效果
感谢大家的支持,这几天从早忙到晚,一个字累呀!!!现在挺困的,但是又不习惯这么早睡觉,哎~~还是利用这个时间继续来写第三篇吧. 前两篇已经基本向大家介绍了绘图的基本知识.那么,我就用我们上两篇所学的,做几个例子. 我们先来做一个简单的----仿QQ截图,关于这个…

POJ 1236 Network of Schools(tarjan)
Network of SchoolsDescription A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B …

如何设置网页自动刷新(JSP,JS,HTML)
http://blog.163.com/ylx282006126/blog/static/59772717201111685917664/ 转载于:https://www.cnblogs.com/liuzhuqing/p/7480284.html

1084 Broken Keyboard
两个注意的点 1.本题被归到散列专题下,但是由于是逐字符地映射到整形,可以直接把布尔型哈希数组的大小设置为ASCII的数量128,然后直接将字符作为数组下标(如果是字符串,才需要自己写一个哈希函数,将字符串映射到整形&…

Android提示框与通知的使用
1.通知 Android 3.0以前使用的方法 1 NotificationManager nm (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 2 Notification notification new Notification(R.drawable.dss, 3 "通知到了", Syste…

nginx安全日志分析脚本的编写
https://blog.csdn.net/nextdoor6/article/details/51914966

[转]笑死人的考试填空
高考完后又是中考,考题千奇百怪,答卷也五花八门。真佩服现在的学生啊,思维跳脱,天马行空,和我们那时候的循规蹈矩,差别太大了,呵呵。看一组语文试卷中的填空题:1.__________…

1033 旧键盘打字
1. 非常奇怪,明明都说了用下划线替代空格,但是用scanf读入的时候就会有1个测试点没通过,换成cin.getline就通过了 2.3种情况下对应的哈希表赋值为true。1是上来就赋值,2是对于大写字母把对应小写字母也赋值,这里注意直…

OLE 操作Excel 详解(转)
使用Excel模板进行报表的开发. 今年搞的Excel比较多,总结了一下,相信常用的操作包含的差不多了。 可以首先定义一个无内容的Excel报表模板文件. 通过Tcode SMW0 上传至SAP数据库中备用.(注: Web对象应该选择’WebRFC 应用程序的二进制数据’) 开发程序…

只需3分钟,就能轻松创建 一个SpreadJS的React项目
概述SpreadJS 纯前端表格控件 V11.2(SP2) 已经全面支持了 React 的拓展。接下来我们看下如何利用3分钟快速创建一个 SpreadJS 的 React 项目。1.新建React 项目(耗时 1 Min)直接运行:npx create-react-app react-spread-sheets还不清楚什么是…

1039 到底买不买
很典型的散列题,对于shop和eva有的珠子(即字符),各开一个128长度的整形散列表计数,将字符作为下标读入。 然后从0~127进行遍历,看每个下标下两个散列表的数量,如果有shop<eva说明不买,但是遍历仍然要继…

什么是Linq
最近一直利用业余的时间来研究Linq,估计这样的文章在对于园子里很多牛人来说就有点小儿科了,前段时间写了一个Linq To Sql体验的小例子,感觉很简洁程序上操作体验不错,我写这些的文章目的是自我学习笔记的备用和查看,当…

OSS正式支持IPv6公测
背景 6月20日阿里云宣布全面支持IPv6, 随后阿里云开放对象存储OSS也逐步开始向用户公测。 公测步骤 正常使用IPv6服务,除了OSS端支持还需要客户端支持,我们做一些检查证明客户端具备访问 IPv6的能力,再使用OSS SDK或工具通过IPv6 …

C++中定义类的对象:用new和不用new的区别
Point p1; Point *p2new Point(); p1 由系统创建并释放,不用担心会出现内存泄露,但是生命期只有在本区域的大括号内,出了大括号就没用了。 P2 是指针,要自己释放,用不好很危险,用好了功能强大,…

1043 输出PATest
开一个长度为6的整型数组分别记录6个字符的数量,输出的时候条件是数组中至少存在一个不为零的元素 while(PATest[0]||PATest[1]||PATest[2]||PATest[3]||PATest[4]||PATest[5]){//当6个还有一个不为0 AC代码 #include<cstdio> #include<cmath> #inc…

[转载 js] YUI解决mouseout事件冒泡的办法
原文出处:http://design.alibaba-inc.com/?qnode/727================&am…

adodb.RecordSet的属性和方法
为了更精确地跟踪数据,要用RecordSet组件创建包括数据的游标,游标就是储存在内存中的数据: rs Server.CreateObject("ADODB.RecordSet") rs.Open(sqlStr,conn,1,A) 注:A1表示读取数据;A3表示新增、改动或删…

给女友讲讲设计模式——适配器模式(JAVA实例)5
前言 有这样一个人,看到别人一个个开餐馆赚了好多钱,于是自己也很想在餐饮业这方面大展拳脚,他从别人那里学到了他们的理念,还学习到了他们真正开店的经验。不但如此,他还引进了除了吃饭意外其他的服务,例如…

1041 Be Unique
1.依旧是散列题,开一个整形的哈希数组bets[10010]来计数,最后数目为1的,也就是unique 2.注意,可能为1的不止一个,要输出第一个输入的unique,那么需要记录下读入的顺序,可以开辟一个数组inputs[…