生产者-消费者模式是一个经典的多线程并发协作模式,对并发编程有着重要的意义。理解生产者-消费者问题有助于加深对并发编程的理解。
生产者-消费者模式包含两类线程:生产者线程用于生产数据,消费者线程用于消费数据。为了解耦生产者和消费者的关系,通常采用共享的数据区域,就像是一个仓库。生产者生产数据后直接放置在共享数据区中,不需要关心消费者的行为;而消费者只需要从共享数据区中获取数据,不需要关心生产者的行为。
共享数据区域应该具备以下线程间并发协作功能:
在实现生产者消费者问题时,可以采用三种方式:
BlockingQueue实现生产者-消费者:
BlockingQueue提供了可阻塞的插入和移除的方法。当队列容器已满,生产者线程会被阻塞,直到队列未满;当队列容器为空时,消费者线程会被阻塞,直至队列非空时为止。有了这个队列,生产者只需要关注生产,而不用管消费者的消费行为,更不用等待消费者线程执行完;消费者也只管消费,不用管生产者是怎么生产的,更不用等着生产者生产。
示例代码:
public class ProductorConsumer {
// 省略部分代码
}
synchronized实现生产者-消费者:
这其实也是手动实现阻塞队列的方式。示例代码:
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CyclicBarrier;
public class MyBlockingQueue {
// 省略部分代码
}
Condition实现生产者-消费者:
示例代码:
public class BoundedQueue {
// 省略部分代码
}
生产者-消费者模式的应用场景:
生产者-消费者模式一般用于将生产数据的一方和消费数据的一方分割开来,将生产数据与消费数据的过程解耦开来。
应用场景包括:
通过将任务的提交和任务的执行解耦开来,提交任务的操作相当于生产者,执行任务的操作相当于消费者。
双十一的时候,会产生大量的订单,需要将订单放入一个队列里面,然后由专门的线程处理订单。
比如上传附件并处理,可以将用户上传和处理附件分成两个过程,用一个队列暂时存储用户上传的附件,然后立刻返回用户上传成功,然后有专门的线程处理队列中的附件。
生产者-消费者模式的优点:
关于作者:
本文已收录于作者的个人博客:
https://www.seven97.top
。公众号:seven97,欢迎关注~