生产者消费者模式学习
这名字可能对没听说过的朋友来说会有点莫名其妙,不过当你看过此文后应该会对其有个一定了解。由于是笔者的学习笔记,所以不妥之处请留言修改,共同进步。
学习背景:
多人操作一个文件。如网站后台管理人员(多个)往一个文件添加数据。具体例子如添加图书信息时,同步创建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);//入队列 }