c#多线程之生产者与消费者问题的解决

这两天由于学习的需要,学了一下C#的多线程,并写了个经典生产者与消费者的案例,但从中也发现了一个问题,总体上感觉C#比java在各个方面来说,总是有些不如,也许是长期使用java和刚刚接触C#吧,存在些偏见,言归正转,解决这个多线程问题,有以下几步骤:

1、使用多线程遇到的问题:解决诸如购票、候车等问题时,肯定是并行工作的,当共同访问一块数据时,如果不加锁的机制的话,肯定会造成数据不一致。

2、所谓的线程同步,就是通过加锁的机制,使得同一段代码,某一时刻只有一线程在访问,也就是有个先来后到,可以多个同时读数据,但不能同时写数据。

3、C#中的同步问题的解决,有lock,Monitor,Mutex等方法来解决。

4、具体的代码分析和实现

     首先要进行明确的面向对象分析,然后进行面向对象编码。在这里只将最核心的同步代码如些:

//此类用来模拟篮子,用来放馒头,并将它比作栈来处理,可以先进后出,后进先出的进行操作

    class Basket//用篮子模拟放馒头的集合

    {

        public static int max_capability = 0;//篮子中最大可以放的馒头数目

        public ManTou[] manTous = null;//声明馒头的一个数

      public static int index=0;//刚开始时的馒头的数量,此时表明篮子中没有馒头,特别指出它始终指/////向馒头的上一个空格

        public void push(ManTou mt,string producer_name)//模拟栈的放入(压入)操作,即将新生产的一个//馒头压入篮子中

        {

            lock (this)//此处采用简单常用的lock来实现线程的同步

            {

                while (index >= max_capability)//判断是不是篮子已经满了,即数目到了max_capability.

                {

                    Console.WriteLine(producer_name + "等待中");//为了更好看到输出效果

                    Monitor.Wait(this);//此时会释放掉当前对象(this)的锁,当有调用pulseAll时重新回到//此处,并重新得到当前对象(this)锁

                    Console.WriteLine(producer_name + "唤醒了");

                }

                manTous[index++] = mt;//将新生成的ManTou对象放入篮子中

                Console.WriteLine(producer_name+"-生产了: "+mt);

                Monitor.PulseAll(this);//唤醒等待在此对象上的所有线程

            }

        }

        public ManTou pop(string consumer_name)//模拟栈的拿出操作,也就是拿出最顶上的馒头

        {

            ManTou mt = null;

            lock (this)

            {

                while (index == 0)

                {

                    Console.WriteLine(consumer_name+"等待中");

                    Monitor.Wait(this);

                    Console.WriteLine(consumer_name + "唤醒了");

                }

 

                mt = manTous[--index];

 

                Monitor.PulseAll(this);

                Console.WriteLine(consumer_name + "-消费了 : " + mt);

                return mt;//此处有待考虑

            }

        }

        public Basket(int max_capability)

        {

            Basket.max_capability = max_capability;

            manTous=new ManTou[max_capability];

        }

    }

5、重点在于理解lock与Monitor的配合使用,这与java的obj.wait和obj.notifyAll相对应的,试试吧。

这里的代码只是核心部分,如果还有不明白的,可以留言联系,希望对你的学习有帮助。

你可能感兴趣的:(多线程,线程,编码,C#)