C#编写的多生产者多消费者同步问题
// 多个生产者和多个消费者,能生产n个产品的情况 using System;
using System.Threading; public class HoldIntegerSynchronized{ private int[] buffer; //缓冲区 private int occupiedBufferCount = ; private int readPosition = , writePosition = ;
//下一个读到的位置和写到的位置 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 == ){ //多个消费者,所以此处改用while
Console.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 + ) % buffer.Length; DisplayState(Thread.CurrentThread.Name + " reads " + bufferCopy); // 通知,让等待的 生产者线程 进入Started状态,如果生产者处于临界区之外,这句话执行完后他仍然在临界区之外
Monitor.PulseAll(this); // 释放锁
}//lock
return 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 + ) % 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 = ; 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=; count<; count++) {
Thread.Sleep(randomSleepTime.Next(,));
sharedLocation.Buffer = randomSleepTime.Next(,);
}
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 = ;
for (int count=; count<; count++) {
Thread.Sleep(randomSleepTime.Next(,));
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();
Random random = new Random(); Thread[] producerThreads = new Thread[];
Thread[] consumerThreads = new Thread[]; Console.Write("{0,-35}","Operation");
for(int i = ;i < holdInteger.BufferSize;i++){
Console.Write("{0,-9}","Elem " + i);
}
Console.WriteLine("Occupied Count/r/n"); for(int i = ; 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 = ; 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 = ; i < producerThreads.Length;i++){
producerThreads[i].Start();
} for(int i = ; i < consumerThreads.Length;i++){
consumerThreads[i].Start();
}
}
}
C#编写的多生产者多消费者同步问题的更多相关文章
- JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池
/** * 多线程共享数据 * 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行. * 多线程共享数据的安全问题,使用同步解决. * 线程同步两 ...
- java多线程(同步与死锁问题,生产者与消费者问题)
首先我们来看同步与死锁问题: 所谓死锁,就是A拥有banana.B拥有apple. A对B说:你把apple给我.我就把banana给你. B对A说:你把banana给我,我就把apple给你. 可是 ...
- [原创]如何编写多个阻塞队列连接下的多生产者多消费者的Python程序
平常在写程序时,往往会遇到一个需求:在程序的多个阶段都会出现阻塞的可能,因此,这多个阶段就需要并发执行. Python的多线程有一个特点,就是不允许从外部结束一个运行中的线程,这给我们编写代码时带来了 ...
- java多线程(同步和死锁,生产者和消费者问题)
首先我们来看看同步与死锁: 所谓死锁.这是A有banana,B有apple. A至B说:你把apple对我来说,,我会banana给你. B至A说:你把banana对我来说,,我会apple给你. 可 ...
- 同步锁Lock & 生产者和消费者案例
显示锁 Lock ①在 Java 5.0 之前,协调共享对象的访问时可以使用的机 制只有 synchronized 和 volatile . Java 5.0 后增加了一些 新的机制,但并不是一种替代 ...
- 【原创】JMS生产者和消费者【PTP同步接收消息】
一般步骤: 请求一个JMS连接工i厂. 是用连接工厂创建连接. 启动JMS连接. 通过连接创建session. 获取一个目标. 创建一个生产者,或a.创建一个生产者,b.创建一条JMS消息并发送到目标 ...
- Java实现PV操作 | 生产者与消费者
导语 在学习操作系统的过程中,PV操作是很重要的一个环节.然而面对书本上枯燥的代码,每一个爱好技术的人总是想能亲自去实现.现在我要推出一个专题,专门讲述如何用Java实现PV操作,让操作系统背后的逻辑 ...
- JAVA并发框架之Semaphore实现生产者与消费者模型
分类: Java技术 锁和信号量(Semaphore)是实现多线程同步的两种常用的手段.信号量需要初始化一个许可值,许可值可以大于0,也可以小于0,也可以等于0. 如果大于0,表示 ...
- 线程操作案例--生产者与消费者,Object类对线程的支持
本章目标 1)加深对线程同步的理解 2)了解Object类中对线程的支持方法. 实例 生产者不断生产,消费者不断消费产品. 生产者生产信息后将其放到一个区域中,之后消费者从区域中取出数据. 既然生产的 ...
随机推荐
- Linux man命令数字含义
1,用户在shell环境中可以操作的命令或可执行文件 2,系统内核可调用的函数与工具等,即由内核提供的函数. 如open,write之类的(通过这个,可以很方便的查到调用这个函数时需要加什么头文件 ...
- python2.7系列安装失败的办法
在windows系统上安装python时出现"there is a problem with your Windows installer package. A program run as ...
- CMake 入门
编写 CMakeLists.txt 首先编写 CMakeLists.txt 文件,并保存在与 main.cc 源文件同个目录下: # 单个源文件 # CMake 最低版本号要求 cmake_minim ...
- javascript --- jQuery --- Deferred对象
javascript --- jQuery --- Deferred对象 javascript的函数式编程是多么引人入胜,jQuery使代码尽可能的精简,intelligent! defer - 必应 ...
- ps制作哈7海报字体
模仿也需要较强的功底和分析思路.如下面的教程,作者模仿的是电影海报字.文字构造虽不复杂,不过思路不对的话就容易走弯路.最终效果 1.先来分析文字的构造,大致由两部分组成,一部分是浮雕字,另一部分是质感 ...
- c# webbrowser获取滚动条最大值
int HeightMax = 0; int WidthMax =0; HeightMax = webBrowser1.Document.Body.ScrollRectangle.Height-web ...
- php 扩展apc 参数优化
编辑php.ini 输入下面 [apc] apc.enabled=1apc.shm_segments = 1apc.shm_size = 1Gapc.ttl = 0apc.user_ttl = 0ap ...
- rhel及相关linux系统版本知识
Rhel 此处Rhel非等同redhat哦,RedHat是红帽公司在1994年左右开发维护的linux桌面版本,在2004年左右红帽公司放弃redhat开始进军linux服务器版本开发,具体见下截图 ...
- Android NDK调试C++源码(转)
[原创文章,转载请保留或注明出处,http://download.csdn.net/download/bigmaxim/5474055] 1. 相关软件 adt-bundle-windows-x86. ...
- C++11用于计算函数对象返回类型的统一方法
[C++11用于计算函数对象返回类型的统一方法] 模板 std::result_of 被TR1 引进且被 C++11 所采纳,可允许我们决定和使用一个仿函数其回返值的类别.底下,CalculusVer ...