Java多线程与高并发专题——生产/消费者模式

引入

我们的很多技术设计思路都来源于生活,生产/消费者模式也不例外。在现实世界中,我们把生产商品的一方称为生产者,把消费商品的一方称为消费者,有时生产者的生产速度特别快,但消费者的消费速度跟不上,就是所谓的“产能过剩”,相反,有时消费者的消费速度大于生产者的生产速度,也就是所谓的“供不应求”。

什么是生产/消费者模式?

生产/消费者模式是一种经典的程序设计模式。

其设计思路正如其名,通过两类角色,即生产者和消费者来实现。生产者负责生成数据或任务,并将其放入一个共享的缓冲区中;消费者则从缓冲区中获取数据或任务并进行处理。生产者和消费者之间通过缓冲区进行解耦,它们不需要直接相互通信或了解对方的具体工作细节,只需要关注缓冲区的状态和操作。

其核心优势:

  1. 解耦:生产者和消费者之间相互独立,它们只需要关注自己的生产和消费行为,而不需要了解对方的具体实现细节。这样可以降低系统的耦合度,提高系统的可维护性和可扩展性。
  2. 提高性能:生产者和消费者可以并行工作,生产者可以在消费者处理数据的同时继续生产数据,从而提高系统的整体性能。
  3. 缓冲作用:缓冲区可以起到缓冲数据的作用,当生产者生产数据的速度大于消费者消费数据的速度时,缓冲区可以暂存数据,避免数据丢失;当消费者消费数据的速度大于生产者生产数据的速度时,缓冲区可以提供数据,保证消费者不会因为没有数据而等待。

在java并发编程时,要实现生产/消费者模式,通常需要在两者之间增加一个阻塞队列作为媒介,有了媒介之后就相当于有了一个缓冲,平衡了两者的能力,整体的设计如上图所示,最上面是阻塞队列,左侧是生产者线程,生产者在生产数据后将数据存放在阻塞队列中,右侧是消费者线程,消费者获取阻塞队列中的数据。而中间分别代表生产者消费者之间互相通信的过程,因为无论阻塞队列是满还是空都可能会产生阻塞,阻塞之后就需要在合适的时机去唤醒被阻塞的线程。

那么什么时候阻塞线程需要被唤醒呢?

主要有两种情况:

  1. 当消费者看到阻塞队列为空时,开始进入等待,这时生产者一旦往队列中放入数据,就会通知所有的消费者,唤醒阻塞的消费者线程。
  2. 如果生产者发现队列已经满了,也会被阻塞,而一旦消费者获取数据之后就相当于队列空了一个位置,这时消费者就会通知所有正在阻塞的生产者进行生产。

相关重要方法的使用注意事项

我们通过下面几个问题去梳理 wait/notify/notifyAll 方法的使用注意事项。

为什么 wait 方法必须在 synchronized 保护的同步代码中使用?

wait 方法的源码注释如下:

    /**
     * Causes the current thread to wait until another thread invokes the
     * {@link java.lang.Object#notify()} method or the
     * {@link java.lang.Object#notifyAll()} method for this object.
     * In other words, this method behaves exactly as if it simply
     * performs the call {@code wait(0)}.
     * <p>
     * The current thread must own this object's monitor. The thread
     * releases ownership of this monitor and waits until another thread
     * notifies threads waiting on this object's monitor to wake up
     * either through a call to the {@code notify} method or the
     * {@code notifyAll} method. The thread then waits until it can
     * re-obtain ownership of the monitor and resumes execution.
     * <p>
     * As in the one argument version, interrupts and spurious wakeups are
     * possible, and this method should always be used in a loop:
     * <pre>
     * 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄雪超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值