// 多个生产者和多个消费者,能生产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#编写的多生产者多消费者同步问题的更多相关文章

  1. JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池

    /** * 多线程共享数据 * 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行. * 多线程共享数据的安全问题,使用同步解决. * 线程同步两 ...

  2. java多线程(同步与死锁问题,生产者与消费者问题)

    首先我们来看同步与死锁问题: 所谓死锁,就是A拥有banana.B拥有apple. A对B说:你把apple给我.我就把banana给你. B对A说:你把banana给我,我就把apple给你. 可是 ...

  3. [原创]如何编写多个阻塞队列连接下的多生产者多消费者的Python程序

    平常在写程序时,往往会遇到一个需求:在程序的多个阶段都会出现阻塞的可能,因此,这多个阶段就需要并发执行. Python的多线程有一个特点,就是不允许从外部结束一个运行中的线程,这给我们编写代码时带来了 ...

  4. java多线程(同步和死锁,生产者和消费者问题)

    首先我们来看看同步与死锁: 所谓死锁.这是A有banana,B有apple. A至B说:你把apple对我来说,,我会banana给你. B至A说:你把banana对我来说,,我会apple给你. 可 ...

  5. 同步锁Lock & 生产者和消费者案例

    显示锁 Lock ①在 Java 5.0 之前,协调共享对象的访问时可以使用的机 制只有 synchronized 和 volatile . Java 5.0 后增加了一些 新的机制,但并不是一种替代 ...

  6. 【原创】JMS生产者和消费者【PTP同步接收消息】

    一般步骤: 请求一个JMS连接工i厂. 是用连接工厂创建连接. 启动JMS连接. 通过连接创建session. 获取一个目标. 创建一个生产者,或a.创建一个生产者,b.创建一条JMS消息并发送到目标 ...

  7. Java实现PV操作 | 生产者与消费者

    导语 在学习操作系统的过程中,PV操作是很重要的一个环节.然而面对书本上枯燥的代码,每一个爱好技术的人总是想能亲自去实现.现在我要推出一个专题,专门讲述如何用Java实现PV操作,让操作系统背后的逻辑 ...

  8. JAVA并发框架之Semaphore实现生产者与消费者模型

    分类: Java技术      锁和信号量(Semaphore)是实现多线程同步的两种常用的手段.信号量需要初始化一个许可值,许可值可以大于0,也可以小于0,也可以等于0.      如果大于0,表示 ...

  9. 线程操作案例--生产者与消费者,Object类对线程的支持

    本章目标 1)加深对线程同步的理解 2)了解Object类中对线程的支持方法. 实例 生产者不断生产,消费者不断消费产品. 生产者生产信息后将其放到一个区域中,之后消费者从区域中取出数据. 既然生产的 ...

随机推荐

  1. 【Linux】Mutex互斥量线程同步的例子

    0.互斥量  Windows下的互斥量 是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致. 当多次Wait**时就 ...

  2. 【Java多线程】两种基本实现框架

    Java多线程学习1——两种基本实现框架 一.前言 当一个Java程序启动的时候,一个线程就立刻启动,改程序通常也被我们称作程序的主线程.其他所有的子线程都是由主线程产生的.主线程是程序开始就执行的, ...

  3. C#面向对象基础01

    面向对象不是取代面向过程的类.对象."人"是类,"张三"是人这个类的对象.类是抽象的,对象是具体的.按钮就是类,某个按钮就是对象.对象可以叫做类的实例.类就像i ...

  4. VHDL之Port map and open

    编SPI的master控制器,使用公司基本的元件,有些端口用不着,恰巧好二哥(不知年龄的数字组组长,本名Holger)来了,于是请教之,告曰open关键词.后来深感自己VHDL水平太水,下了一本电子书 ...

  5. Maven,预加载资源文件

    预加载资源文件需要先启用功能: <build> <resources> <resource> <directory>src/main/resources ...

  6. Oracle 游标使用(转)

    这个文档几乎包含了oracle游标使用的方方面面,全部通过了测试 ; ; dbms_output.put_line(sql) loop dbms_output.put_line( ; ; ; r_te ...

  7. dom div重合提示

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  8. MVC缓存的使用

    MVC3缓存之一:使用页面缓存 在MVC3中要如果要启用页面缓存,在页面对应的Action前面加上一个OutputCache属性即可. 我们建一个Demo来测试一下,在此Demo中,在View的Hom ...

  9. 在WP8上搭建cocos2d-x开发环境

    在WP8上搭建cocos2d-x开发环境 转自:https://github.com/koowolf/cocos-docs/blob/master/manual/framework/native/in ...

  10. 让CSS3给你的文字加上边框宽度,并实现镂空效果

    这次,我主要向大家介绍一下CSS3下的-webkit-text-stroke属性,并分享几个用该属性制作的镂空文字效果. 1.-webkit-text-stroke属性简介 CSS边框的一个不足就是只 ...