线程的同步和通讯——生产者和消费者 (VS .NET控制台)

/// <summary>
    /// 三.线程的同步和通讯——生产者和消费者 
    /// </summary>

    /*首先,我们定义一个被操作的对象的类Cell,
     * 在这个类里,有两个方法:ReadFromCell()和WriteToCell()。
     * 消费者线程将调用ReadFromCell()读取cellContents的内容并且显示出来,
     * 生产者进程将调用WriteToCell()方法向cellContents写入数据。*/
    public class Cell
    {
        int cellContents; // Cell对象里边的内容
        bool readerFlag = false; // 状态标志,为true时可以读取,为false则正在写入

        //消费者
        public int ReadFromCell()
        {
            lock (this)
            {
                if (!readerFlag)//如果现在不可读取
                {
                    try
                    {
                        //等待WriteToCell方法中调用Monitor.Pulse()方法
                        Monitor.Wait(this);
                    }
                    catch (SynchronizationLockException e)
                    {
                        Console.WriteLine(e);
                    }
                    catch (ThreadInterruptedException e)
                    {
                        Console.WriteLine(e);
                    }
                }
                Console.WriteLine("Consume: {0}", cellContents);
                readerFlag = false; //重置readerFlag标志,表示消费行为已经完成
                Monitor.Pulse(this); //通知WriteToCell()方法(该方法在另外一个线程中执行,等待中)
            }
            return cellContents;
        }

        //生产者
        public void WriteToCell(int n)
        {
            lock (this)
            {
                if (readerFlag)
                {
                    try
                    {
                        Monitor.Wait(this);
                    }
                    catch (SynchronizationLockException e)
                    {
                        //当同步方法(指Monitor类除Enter之外的方法)在非同步的代码区被调用
                        Console.WriteLine(e);
                    }
                    catch (ThreadInterruptedException e)
                    {
                        //当线程在等待状态的时候中止 
                        Console.WriteLine(e);
                    }
                }
                cellContents = n;
                Console.WriteLine("Produce: {0}", cellContents);
                readerFlag = true;
                Monitor.Pulse(this);
                //通知另外一个线程中正在等待的ReadFromCell()方法
            }
        }
    }


    /*下面定义生产者CellProd和消费者类CellCons,它们都只有一个方法ThreadRun(),
     * 以便在Main()函数中提供给线程的ThreadStart代理对象,作为线程的入口。*/
    public class CellProd//生产者类
    {
        Cell cell; // 被操作的Cell对象
        int quantity = 1; // 生产者生产次数,初始化为1 

        public CellProd(Cell box, int request)
        {
            //构造函数
            cell = box;
            quantity = request;
        }

        public void ThreadRun()
        {
            for (int looper = 1; looper <= quantity; looper++)
                cell.WriteToCell(looper); //生产者向操作对象写入信息
        }
    }


    public class CellCons//消费者类
    {
        Cell cell;
        int quantity = 1;

        public CellCons(Cell box, int request)
        {
            cell = box;
            quantity = request;
        }

        public void ThreadRun()
        {
            int valReturned;
            for (int looper = 1; looper <= quantity; looper++)
                valReturned = cell.ReadFromCell();//消费者从操作对象中读取信息
        }
    }

   
    /*然后在下面这个类Program的Main()函数中我们要做的就是创建两个线程分别作为生产者和消费者,
     * 使用CellProd.ThreadRun()方法和CellCons.ThreadRun()方法对同一个Cell对象进行操作。*/
    class Program
    {
        static void Main(string[] args)
        {
            int result = 0;
            //一个标志位,如果是0表示程序没有出错,如果是1表明有错误发生
            Cell cell = new Cell();

            //下面使用cell初始化CellProd和CellCons两个类,生产和消费次数均为20次
            CellProd prod = new CellProd(cell, 20);
            CellCons cons = new CellCons(cell, 20);

            Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
            Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
            //生产者线程和消费者线程都已经被创建,但是没有开始执行 

            try
            {
                producer.Start();
                consumer.Start();

                producer.Join();
                consumer.Join();
                Console.ReadLine();
            }
            catch (ThreadStateException e)
            {
                //当线程因为所处状态的原因而不能执行被请求的操作
                Console.WriteLine(e);
                result = 1;
            }
            catch (ThreadInterruptedException e)
            {
                //当线程在等待状态的时候中止
                Console.WriteLine(e);
                result = 1;
            }
            //尽管Main()函数没有返回值,但下面这条语句可以向父进程返回执行结果
            Environment.ExitCode = result;
        }


    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值