设计模式-生产者 消费者

588 阅读3分钟

定义

//维基百科
生产者消费者问题
说明
生产者消费者问题,也称有限缓冲问题,是一个多进程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。


就是两个进程,共享同一个数据。正如,上面所说,共享固定大小缓冲区的两个进程。这两个进程,就是,一个是生产者,一个是消费者。一个写数据,一个读数据。

应用场景-支付系统:支付

目的是为了解耦。因为支付的流程是这样的:
1.扫本地数据 //从数据库,读数据。
写到队列
2.处理本地数据 //写数据到数据库。更新支付状态。
从队列读

现在呢,把1 2分开了。即,把读数据,放到一个独立的服务,去处理。读数据库和写数据库,分离。//从数据库的读写的角度,进行解耦

写队列和读队列,分离。//从集合数据的读写的角度,进行解耦

数据结构-队列ConcurrentLinkedQueue

解释
1.队列 //因为数据处理是按照顺序,具体是先进先出的顺序,所以用队列。只要是对数据进出的顺序有要求的,都是用队列。

2.链表 //是因为数据量比较大。最佳实践,一般来说实现队列数据结构的基础数据结构就是用链表。当然,数组也可以实现队列。

所以,支付系统里,用到的都是链表队列。比如,并发链表队列(支付)。链表阻塞队列(实名认证)。链表阻塞队列(转账),因为线程池默认就是链表阻塞队列。

可以看到,全部是链表队列。其他的,就是是否是阻塞队列,是否是线程安全。

3.线程安全

和观察者模式的区别?

生产者 消费者。和观察者 被观察者,基本上一样。就是一个提供数据,一个消费数据。

消费数据的人在监听数据。提供数据的人在生产数据,并且生产数据之后,还要通知消费者。

代码

1.生产者进程 //写数据到阻塞队列。具体怎么写?调用远程服务(即消费者进行)的方法,写数据到队列。队列数据是在消费者进程里。

2.消费者进程 //遍历队列数据。具体是while循环遍历。具体是:

for(队列不为空){
    读队列数据;
}

两个进程和两个线程

一般来说,线程,也就是生产者线程和消费者线程在同一个进程/jvm内,就是阻塞队列 + while(true)。

for(true){
    阻塞读阻塞队列数据;
}

当然,写也一样,阻塞写阻塞队列数据。


但是,如果是两个进程,生产者进程和消费者进程。那么就是定时任务 + 非阻塞队列 + while(队列大小)。

也就是说,是通过定时任务,来实现不停的处理数据的功能的。而两个线程是通过while(true),来实现不停的处理新到来的数据。

参考

zh.wikipedia.org/wiki/生产者消费者…

juejin.cn/post/684490…

juejin.cn/post/684490…

www.infoq.cn/article/pro…

这些文章都很简单,仅供参考