设计模式—生产者消费者模式

生产者消费者模式是指生产者和消费者通过一个缓冲区(通常是一个队列)的进行通讯。生产者生产完数据之后不用等待消费者处理,直接放到缓冲区,消费者不找生产者要数据,而是直接从缓冲区里取,这样既能够保持生产者和消费者的并发处理,也可以平衡生产者和消费者的处理能力。

这样做有以下优点:

◇ 降低生产者和消费者之间的耦合性

假设生产者和消费者分别是两个类。如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。将来如果消费者的代码发生变化,可能会影响到生产者。而如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。

◇ 生产者和消费者可以并行运行

生产者直接与消费者通信的话,由于函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回之前,生产者只好一直等在那边。万一消费者处理数据很慢,生产者就会白白糟蹋大好时光。

使用了生产者/消费者模式之后,生产者和消费者可以是两个独立的并发主体(常见并发类型有进程和线程两种,后面的帖子会讲两种并发类型下的应用)。生产者把制造出来的数据往缓冲区一丢,就可以再去生产下一个数据。基本上不用依赖消费者的处理速度。

◇ 平衡生产者和消费者的处理能力

缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来了。当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。等生产者的制造速度慢下来,消费者再慢慢处理掉。

下面是一个简单的例子,不包含锁机制

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

namespace DesignPatern
{
    //队列临时类
    public class QueueInfo
    {
        public string ID { get; set; }

        public override string ToString()
        {
            return this.ID;
        }
    }

    public class BusinessInfoHelper
    {
        #region 解决发布时含有优质媒体时,前台页面卡住的现象
        //原理:利用生产者消费者模式进行入列出列操作

        public readonly static BusinessInfoHelper Instance = new BusinessInfoHelper();
        private int N = 100;
        private BusinessInfoHelper()
        {
        }

        private Queue ListQueue = new Queue();

        public void StartProducer()
        {
            Thread thread = new Thread(threadStartProduct);
            thread.Start();
        }

        private void threadStartProduct()
        {
            int k = 0;
            while(true)
            {
                if(ListQueue.Counttry
                    {
                        k++;
                        AddQueue(k.ToString());
                    }
                    catch(Exception ex)
                    {
                        throw new Exception(ex.ToString());
                    }
                }
            }
        }

        public void AddQueue(string pid) //入列
        {
            QueueInfo queueinfo = new QueueInfo();

            queueinfo.ID = pid;
            ListQueue.Enqueue(queueinfo);
        }

        public void StartConsumer()//启动
        {
            Thread thread = new Thread(threadStartConsume);
            thread.IsBackground = true;
            thread.Start();
        }

        private void threadStartConsume()
        {
            while (true)
            {
                if (ListQueue.Count > 0)
                {
                    try
                    {
                        ScanQueue();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                }
                else
                {
                    //没有任务,休息3秒钟
                    Thread.Sleep(3000);
                }
            }
        }

        //要执行的方法
        private void ScanQueue()
        {
            while (ListQueue.Count > 0)
            {
                try
                {
                    //从队列中取出
                    QueueInfo queueinfo = ListQueue.Dequeue();
                    Console.WriteLine(queueinfo.ToString());
                    //取出的queueinfo就可以用了,里面有你要的东西
                    //以下就是处理程序了
                    //。。。。。。
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.ToString());
                }
            }
        }
        #endregion
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace DesignPatern
{
    class Program
    {
        private static object lockObject = new Object(); 
        static void Main(string[] args)
        {
            DesignPatern.BusinessInfoHelper.Instance.StartProducer();
            DesignPatern.BusinessInfoHelper.Instance.StartConsumer();
            //Thread.Sleep(300000);
        }
    }
}

写的不完整等待后续完善。。。

参考资料:
http://blog.csdn.net/kaiwii/article/details/6758942
http://www.infoq.com/cn/articles/producers-and-consumers-mode/#0-tsina-1-97643-397232819ff9a47a7b7e80a40613cfe1

你可能感兴趣的:(#,设计模式)