一、简介

  • 多线程环境下,我们经常需要多个线程的并发和协作。
  • 这个时候,就需要了解一个重要的多线程并发协作模型 "生产者 / 消费者模式 "
  • 模式简图

    • 生产者:负责生产数据的模块(模块可能是:方法、对象、线程、进程)。
    • 消费者:是负责处理数据的模块(模块可能是:方法、对象、线程、进程)。
    • 缓冲区: 消费者不能直接使用生产者的数据,它们之间有个“缓冲区”。

      • 缓冲区是实现并发的核心
      • 生产者将生产好的数据放入“缓冲区”
      • 消费者从“缓冲区”拿要处理的数据。

二、优点

2.1 解耦

  • 2.1.1 耦合:如果生产者直接调用消费者的某个方法,生产者则对消费者产生依赖

    • 生活寄邮件例子:

      • @寄件人(生产者)
      • @邮筒(缓冲区)
      • @收件人(消费者)
      • 寄件人如果不使用邮箱,ta必须得把信直接交给邮递员(某个方法),才能送到收件人,这就产生你和邮递员之间的依赖
  • 2.1.2 解耦:生产者不需要和消费者直接打交道。

2.2 支持并发(concurrency)

  • 2.2.1 缓冲区的优点:

    • 对于生产者:生产者线程只需要往缓冲区里面放置数据,无需管消费者消费的情况。
    • 对于消费者:消费者只需从缓冲区拿数据处理,无需管生产者生产的情况

2.3 解决忙闲不均,提高效率

  • 对于消费者:当生产者生产数据缓慢时,缓冲区仍有数据,不影响消费者消费
  • 对于生产者:消费者处理数据慢时,生产者仍然可以继续往缓冲区里面放置数据 。

三、应用场景

  • 线程并发协作(也叫线程通信),通常用于生产者/消费者模式,情景如下:

    • 共享资源:生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件。
    • 对于生产者:没有生产产品之前,消费者要进入等待状态。而生产了产品之后,又需要马上通知消费者消费。
    • 对于消费者:在消费之后,要通知生产者已经消费结束,需要继续生产新产品以供消费。
    • 分析不足:在生产者消费者问题中,仅有synchronized是不够的。

      • synchronized可阻止并发更新同一个共享资源,实现了同步;
      • synchronized不能用来实现不同线程之间的消息传递(通信)
    • 实现需要的主要方法:

以上方法均是java.lang.Object类的方法;都只能在同步方法或者同步代码块中使用,否则会抛出异常

  • “架构设计”中,会大量使用这个模式。暂时作为了解

四、总结


wdt0x01
29 声望2 粉丝