一、简介
- 多线程环境下,我们经常需要多个线程的并发和协作。
- 这个时候,就需要了解一个重要的多线程并发协作模型 "生产者 / 消费者模式 "。
-
模式简图
- 生产者:负责生产数据的模块(模块可能是:方法、对象、线程、进程)。
- 消费者:是负责处理数据的模块(模块可能是:方法、对象、线程、进程)。
-
缓冲区: 消费者不能直接使用生产者的数据,它们之间有个“缓冲区”。
- 缓冲区是实现并发的核心
- 生产者将生产好的数据放入“缓冲区”
- 消费者从“缓冲区”拿要处理的数据。
二、优点
2.1
解耦
-
2.1.1 耦合:如果生产者直接调用消费者的某个方法,生产者则对消费者产生依赖
-
生活寄邮件例子:
- @寄件人(生产者)
- @邮筒(缓冲区)
- @收件人(消费者)
- 寄件人如果不使用邮箱,ta必须得把信直接交给邮递员(某个方法),才能送到收件人,这就产生你和邮递员之间的依赖
-
- 2.1.2 解耦:生产者不需要和消费者直接打交道。
2.2
支持并发(concurrency)
-
2.2.1 缓冲区的优点:
- 对于生产者:生产者线程只需要往缓冲区里面放置数据,无需管消费者消费的情况。
- 对于消费者:消费者只需从缓冲区拿数据处理,无需管生产者生产的情况
2.3
解决忙闲不均,提高效率
- 对于消费者:当生产者生产数据缓慢时,缓冲区仍有数据,不影响消费者消费
- 对于生产者:消费者处理数据慢时,生产者仍然可以继续往缓冲区里面放置数据 。
三、应用场景
-
线程并发协作(也叫线程通信),通常用于生产者/消费者模式,情景如下:
- 共享资源:生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件。
- 对于生产者:没有生产产品之前,消费者要进入等待状态。而生产了产品之后,又需要马上通知消费者消费。
- 对于消费者:在消费之后,要通知生产者已经消费结束,需要继续生产新产品以供消费。
-
分析不足:在生产者消费者问题中,仅有
synchronized
是不够的。-
synchronized
可阻止并发更新同一个共享资源,实现了同步; -
synchronized
不能用来实现不同线程之间的消息传递(通信)
-
- 实现需要的主要方法:
- “架构设计”中,会大量使用这个模式。暂时作为了解
四、总结
- 略
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。