生产者与消费者问题

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ThreadTestProject
{
   
//LetSynchronized用来存放和取出缓冲区变量

   
public class LetSynchronized
    {
       
//定义了只有三个字节的缓冲区
        private int[] buffer =new int[1];

       
//确认缓冲区内已放数值的个数
        private int bufferCount = 0;

       
//确定读写的位置
        private int readLocation = 0, writeLocation = 0;

       
public LetSynchronized()
        {

        }

       
public int getBuffer()
        {
           
//加上了共享锁
            lock (this)
            {
               
//判断如果缓冲区内无内容,则Consumer进入wait状态,并且释放对象锁
                if (bufferCount == 0)
                {
                    Console.WriteLine(
"缓冲区无数据,消费者无法读取");
                    Monitor.Wait(
this);
                }
               
//Thread.Sleep(1000);
                int readValue = buffer[readLocation];
               
//已经从缓冲区读取了内容,所以bufferCount要进行自减.
                bufferCount--;
               
//求余的目的是为了循环使用缓冲区
                readLocation = (readLocation + 1) % buffer.Length;
               
//通知对象的第一个等待线程可以从WaitSleepJoin转换到Started状态.
                Monitor.Pulse(this);
               
//返回给consumer取出的数值
                return readValue;
                }
        }

       
//将数据放入缓冲区
        public void setBuffer(int writeValue)
        {
           
//锁住共享数据区
            lock (this)
            {
               
//如果缓冲区已满,那么进入waitsleepjoin状态
                if (bufferCount == buffer.Length)
                {
                    Console.WriteLine(
"缓冲区满了,等待消费...!");
                    Monitor.Wait(
this);
                }
               
//Thread.Sleep(1000);
               
//向缓冲区写入数据
                buffer[writeLocation] = writeValue;
               
//自加,代表缓冲区现在到底有几个数据
                bufferCount++;
               
//用%实现缓冲区的循环利用
                writeLocation = (writeLocation + 1) % buffer.Length;
               
//唤醒waitSleepJoin状态的进程,到started状态
                Monitor.Pulse(this);
               
//使用lock隐式的释放了共享锁
            }
        }
    }

   
//生产者类,向缓冲区中放入数据
    public class Producer
    {
       
//定义了同步变量
        LetSynchronized shared;

       
//此处构造函数的作用是在启动类中调用Producer的时候,把启动类中定义的sharedLocation传过来
        public Producer(LetSynchronized sharedLocation)
        {
            shared
= sharedLocation;
        }

       
//定义生产过程
        public void produce()
        {
           
//将数据放入缓冲区
            for (int count = 1; count <= 5; count++)
            {
                shared.setBuffer(count);
                Console.WriteLine(
"生产者向缓冲区中写入 " + count);
            }

           
//得到当前线程的名字
            string name = Thread.CurrentThread.Name;
           
//此线程执行完毕
            Console.WriteLine(name + "生产完毕!");
        }
    }

   
//定义消费者类
    public class Consumer
    {
       
private int value;

       
//定义同步变量
        LetSynchronized shared;

       
//定义构造函数,负责传递启动类中的shared
        public Consumer(LetSynchronized sharedLocation)
        {
            shared
= sharedLocation;
        }

       
//从缓冲区中循环读取
        public void consume()
        {
           
for (int count = 1; count <= 5; count++)
            {
                value
= shared.getBuffer();
                Console.WriteLine(
"消费者从缓冲中读取了数据 " + value);
            }

           
//取得当前线程的名字
            string name = Thread.CurrentThread.Name;
            Console.WriteLine(name
+ "消费完毕");
        }
    }


   
//设置为启动类
    public class ThreadTest
    {
       
public static void Main()
        {
            LetSynchronized shared
= new LetSynchronized();

           
//初始化了生产者和消费者,并且把shared参数传递了过去
            Producer producer1 = new Producer(shared);
            Consumer consumer1
= new Consumer(shared);

           
//定义了一个producerThread线程,new Thread是构造Thread
           
//后面的那个new 则是启动一个新的线程,线程启动的方法是producer1.produce
            Thread producerThread = new Thread(new ThreadStart(producer1.produce));
            producerThread.Name
= "生产者";

           
//同上
            Thread consumerThread = new Thread(new ThreadStart(consumer1.consume));
            consumerThread.Name
= "消费者";

           
//启动这两个线程
            producerThread.Start();
            consumerThread.Start();
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值