Java 生产者消费者模式
简介
生产者消费者模式并不是GOF提出的23种设计模式之一,23中设计模式是建立在面向对象的基础上的,但其实面向过程的编程中也有很多高校的编程模式,生产者消费者模式便是其中之一,它是我们编程过程中最常用的一种设计模式。
在实际的软件开发中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理。产生数据的模块,就形象地称为生产者,而处理数据的模块,就称为消费者。
单单抽象出生产者和消费者,还不够称之为生产者消费者模式。该模式还需要有一个缓冲区处于生产者金额消费者之间,作为一个中介,生产者把数据放入缓冲区,而消费者从缓冲区取出数据,大概的结构图如下图:
在网上有一个很好的例子:就是寄信,假设你要寄一封信,那么大致过程如下:
1.首先,你要把信写好-------------------相当于生产者制造数据
2.你要把写好的信放在邮筒--------------------相当于生产者把数据放入缓冲区
3.邮递员把信从信箱取出---------------------相当于消费者把数据去除缓冲区
4.邮递员把信拿去邮局做相应的处理----------------相当于消费者处理数据
优点
1.解耦
假设生产者消费者分别是两个类,如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖。将来如果消费者的代码改变,可能会影响到生产者。而如果两个类都依赖于某个缓冲区,两者之间不直接依赖,那么耦合也就降低了。
2.支持并发(concurrency)
生产者直接调用消费者的某个方法,还有另一个弊端,就是函数调用是同步的,或者叫阻塞的,如果不清楚概念可以去找找多线程基础,如果多线程情况下,生产者调用了消费者的方法,那么如果消费者的方法在没有返回之前,那么生产者就只好一直等在那边队列。网易消费者处理数据很慢,生产者就一直在那等,很浪费时间。
如果使用了生产者消费者模式,那么生产者和消费者是两个独立的并发主体,生产者就没有直接依赖于消费者,而是生产者直接把制造出来的数据往缓存区一丢,他就可以接着去生成下一个数据,基本上不用依赖消费者的处理速度。
3.支持忙闲不均
缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来了,当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中,等生产者的制造速度慢下来后,消费者在慢慢处理掉。
数据单元
什么是数据单元,简单来说,每次生产者放放到缓冲区,就是一个数据单元,每次消费者从缓冲区取出的,也是一个数据单元。
数据单元的特性:
1.关联到业务对象:首先,数据单元必须关联某种业务对象
2.完整性:所谓完整性,就是在数据单元传输的过程中,要保证数据单元的完整性,要么整个数据单元传递给消费者,要么完全没有传递给消费者。不允许出现部分传递这种。
3.独立性:所谓独立性,就是各个数据单元之间没有互相依赖,某个数据单元传输失败不影响已经传输成功的单