生产者消费者模式学习

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产者消费者模式学习相关的知识,希望对你有一定的参考价值。

这名字可能对没听说过的朋友来说会有点莫名其妙,不过当你看过此文后应该会对其有个一定了解。由于是笔者的学习笔记,所以不妥之处请留言修改,共同进步。

学习背景:

多人操作一个文件。如网站后台管理人员(多个)往一个文件添加数据。具体例子如添加图书信息时,同步创建Lucene.net的索引。

产生问题:

上面这个情况下,就会产生一个并发的问题,有可能我还没操作完,你也来操作了。

解决:

解决这个问题目前笔者只有两种办法,一个是加锁。操作前将文件加锁,操作完解锁。这样能解决并发的问题,但是试着想想看,多名(可以理解为几百位)管理人员同时操作的时候,

你是运气好,获得了该文件的操作权,而其他哥们就得耐心的等你操作完,文件解锁后才能操作,这样一来,效率会很慢。

技术分享

 

于是,对于这种情况,我们就可以想到队列了(数据结构真该好好学,我的学校将其放在大一教,这不是扯淡吗,那么年轻如何掌握这门技能)。

如下图所示,后台管理不直接与操作文件了,而是将操作信息放到队列中(队列总不会有并发问题了吧),然后由一个后台线程来将其中信息一条条的与文件去进行交互。

技术分享

到这里,对于具体的应用,还有几个问题需要进行进一步说明,那就是这个线程,第1步入队列,可以理解,操作人员来做。

2步,出队列,线程来做,也就是程序来做,那么我们如何来控制呢?我的解决方案是:在应用程序启动的时候开启这个线程,然后就这么一直24小时来扫描我们的队列:

 

public void StartThread()//网站应用程序第一次启动时调用该方法。即开始扫描队列
        {
            Thread myThread = new Thread(CreateIndexContent);
            myThread.IsBackground = true;
            myThread.Start();
        }
private void CreateIndexContent()
        {
            while (true)
            {
                if (queue.Count > 0)
                {
                    你要的操作();
                }
                else
                {
                    Thread.Sleep(3000);//休息会儿,减少对cpu的浪费,避免cpu空转    这里写在了死循环里头,是不是以前都没碰到过这种情况
                }
            }
        }

 

程序在哪儿是启动点呢?找到我们的Global.asax

技术分享

 

接下来,你就可以进行尽情的操作了,只要往我们的队列中添加操作信息(如添加,修改,删除),讲得通俗点,就是往这个队列集合中加一条记录,当然这条记录的类型是你规定的。

Queue<SearchContentIndexModel> queue = new Queue<SearchContentIndexModel>();//这是我们的队列
///</summary>
///入队列例子
///</summary>
public  void AddQueue(string Id, string BookContent, string Images, string Author, string Price1, string Price2, string Price3, string Publisher,string BookName) 
        {
            SearchContentIndexModel indexModel = new SearchContentIndexModel();
            indexModel.Id = Id;
            indexModel.BookContent = BookContent;
            indexModel.BookName = BookName;
            indexModel.Images = Images;
            indexModel.Author = Author;
            indexModel.Price1 = Price1;
            indexModel.Price2 = Price2;
            indexModel.Price3 = Price3;
            indexModel.Publisher = Publisher;
            indexModel.IndexEnum = Model.Enum.IndexEnum.Add;

            queue.Enqueue(indexModel);//入队列
        }

 

以上是关于生产者消费者模式学习的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ学习笔记4:消息模式

RabbitMQ学习笔记4:消息模式

RabbitMQ 学习---- 路由订阅模型

RabbitMQ 学习---- 路由订阅模型

RabbitMQ 学习---- 路由订阅模型

RabbitMQ 学习---- 工作队列模式