首页 > C#编写的多生产者多消费者同步问题

C#编写的多生产者多消费者同步问题

// 多个生产者和多个消费者,能生产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();}}
}

 

转载于:https://www.cnblogs.com/gc2013/p/3959384.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 菜鸟一枚,正在学习C++ Gui Qt4,整理很零碎,欢迎批评指正   1.窗口标题: QWidget *window = new QWidget; window->setWindowTitle("Enter Your Age"); **************************************** 关于标题...

  • 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 总体思路是: 比较两个链表头节点,较小的插入新链表指针之后,同时较小链表指针向后移动一位 实现如下: ListNode* mergeTwo...

  • 1.直接调用微软socket对象处理 static void Main(string[] args){try{IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });//在3721端口新建一个TcpListener对象TcpListener listener = new...

  •   现在很多地方都会用到zookeeper, 用到它的地方就是为了实现分布式。用到的场景就是服务注册,比如一个集群服务器,需要知道哪些服务器在线,哪些服务器不在线。   ZK有一个功能,就是创建临时节点,当机器启动应用的时候就会连接到一个ZK节点,然后创建一个临时节点,那么通过获取监听该路径,并且获取该路径下的节点数量就知道有哪些服务...

  • 前台到后台java时data日期类型的转化 在实体类中用@DataTimeFormat,这样设置即使传过来是空的字符串也是可以转的,要和前面传过来的格式一致,如 @XmlElement(name="BeginDate") @DateTimeFormat(pattern="yyyy-MM-dd") private Date begin...