生产者消费者模式学习

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

学习背景:

多人操作一个文件。如网站后台管理人员(多个)往一个文件添加数据。具体例子如添加图书信息时,同步创建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);//入队列
        }
时间: 2024-12-26 21:25:38

生产者消费者模式学习的相关文章

多线程之生产者消费者模式

最近在项目中需要使用使用多线程实现一种功能,和生产者消费者模式类似,因此,学习了下生产者消费者模式的多线程实现.在生产者消费者模式中,通常有两类线程, 即若干个生产者线程和若干个消费者线程.生产者线程负责提交用户请求,消费者线程则负责处理生产者提交的任务.生产者和消费者之间则通过共享内存缓冲区进行通信. 在这里我们选择BlockingQueue做为共享内存缓冲区. 首先,我们构建生产者生产的,和消费者需要处理的数据PCData,即相关任务数据. public class PCData { pri

java 多线程并发系列之 生产者消费者模式的两种实现

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这种生产消费能力不均衡的问题,所以便有了生产者和消费者模式. 什么是生

环形缓冲区的设计及其在生产者消费者模式下的使用(并发有锁环形队列)

1.环形缓冲区 缓冲区的好处,就是空间换时间和协调快慢线程.缓冲区可以用很多设计法,这里说一下环形缓冲区的几种设计方案,可以看成是几种环形缓冲区的模式.设计环形缓冲区涉及到几个点,一是超出缓冲区大小的的索引如何处理,二是如何表示缓冲区满和缓冲区空,三是如何入队.出队,四是缓冲区中数据长度如何计算. ps.规定以下所有方案,在缓冲区满时不可再写入数据,缓冲区空时不能读数据 1.1.常规数组环形缓冲区 设缓冲区大小为N,队头out,队尾in,out.in均是下标表示: 初始时,in=out=0 队头

整理整理生产者消费者模式,用通俗的话描述

之前学习多线程问题遇到的最大的难度就是,很多:生产者消费者模式是比较经典的多线程问题,看似 不难,但实际上有很多地方值得注意的. 首先是几个问题 问题1 一共有哪些对象? 生产者与消费者是肯定有的,生产者与消费者之间还有一个缓冲区对象,用以保存生产与消费的目标,还有一个对象就是主线程对象,用来运行多个线程的. 追问:为什么要有一个缓冲区对象? 答:为了实现生产者与消费者解耦,互补依赖或者关联. 追问:每个对象都包含哪些变量与方法? 答:生产者包含缓冲区对象并在run()方法里面执行生产调度命令:

生产者消费者模式的java实现(实现三)

Exchanger是java.util.concurrent类库下的一个并发工具.下面是java api文档里对Exchanger的描述. A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches with a partner thread, a

生产者消费者模式(1)

http://blog.csdn.net/kzq_qmi/article/details/46945753 生产者消费者问题(Producer-consumer problem)是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线程--即所谓的"生产者"和"消费者"--在实际运行时会发生的问题.生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区消耗这些数据.该问题的关键就是要保证生产者不会在缓冲区满时加入数据

生产者消费者模式的java实现(实现二)

这次采用ReentrantLock 实现生产者消费者模式,先说下ReentrantLock,通常叫做重入锁,所谓重入就是一个线程可以再次进入已经持有锁的代码块,在内部会对重入的次数进行计数,当计数为0,则释放锁.其实synchronized关键字所代表的内置锁,也是可以重入的.但是又有几点不同: 1.ReentrantLock将加锁与解锁进行分离,可以提供更细粒度的加解锁操作,内置锁基本都是全局锁(类,对象,代码块) 2.ReentrantLock提供了定时的加锁操作,这是内置锁无法做到的. 3

生产者消费者模式的java实现(实现一)

在多线程以及并发工具类中,常用的一种思想就是生产者消费者模式,生产者负责生产物品,将物品放到传送带,消费者负责获取传送带的物品,消费物品.现在只考虑最简单的情况,传送带上只允许放一个物品. 1.传送带为空,则允许生产者放置物品,否则不许放(生产者线程wait). 2.生产者放置完物品后,通知消费者可以拿了(线程通信,notify 或者notifyAll). 2.传送带不空,则允许消费者拿物品,否则不许拿(消费者线程wait). 3.消费者拿走物品后,通知生产者可以继续生产(线程通信,notify

LabVIEW之生产者/消费者模式--队列操作 彭会锋

LabVIEW之生产者/消费者模式--队列操作 彭会锋 本文章主要是对学习LabVIEW之生产者/消费者模式的学习笔记,其中涉及到同步控制技术-队列.事件.状态机.生产者-消费者模式,这几种技术在在本章中都会有侧重点的进行介绍和总结! 队列同步技术-操作函数 同步控制技术可以实现在多个VI之间或者同一VI 不同县城之间同步任务和交换数据:在LabVIEW中提供了‘同步’函数选板,包括通知器.队列.信号量.集合点.事件.首次调用函数,本文主要关注同步控制技术之队列技术: 队列操作函数: 1 “获取