定义
//维基百科
生产者消费者问题
说明
生产者消费者问题,也称有限缓冲问题,是一个多进程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。
就是两个进程,共享同一个数据。正如,上面所说,共享固定大小缓冲区的两个进程。这两个进程,就是,一个是生产者,一个是消费者。一个写数据,一个读数据。
应用场景-支付系统:支付
目的是为了解耦。因为支付的流程是这样的:
1.扫本地数据 //从数据库,读数据。
写到队列
2.处理本地数据 //写数据到数据库。更新支付状态。
从队列读
现在呢,把1 2分开了。即,把读数据,放到一个独立的服务,去处理。读数据库和写数据库,分离。//从数据库的读写的角度,进行解耦
写队列和读队列,分离。//从集合数据的读写的角度,进行解耦
数据结构-队列ConcurrentLinkedQueue
解释
1.队列 //因为数据处理是按照顺序,具体是先进先出的顺序,所以用队列。只要是对数据进出的顺序有要求的,都是用队列。
2.链表 //是因为数据量比较大。最佳实践,一般来说实现队列数据结构的基础数据结构就是用链表。当然,数组也可以实现队列。
所以,支付系统里,用到的都是链表队列。比如,并发链表队列(支付)。链表阻塞队列(实名认证)。链表阻塞队列(转账),因为线程池默认就是链表阻塞队列。
可以看到,全部是链表队列。其他的,就是是否是阻塞队列,是否是线程安全。
3.线程安全
和观察者模式的区别?
生产者 消费者。和观察者 被观察者,基本上一样。就是一个提供数据,一个消费数据。
消费数据的人在监听数据。提供数据的人在生产数据,并且生产数据之后,还要通知消费者。
代码
1.生产者进程 //写数据到阻塞队列。具体怎么写?调用远程服务(即消费者进行)的方法,写数据到队列。队列数据是在消费者进程里。
2.消费者进程 //遍历队列数据。具体是while循环遍历。具体是:
for(队列不为空){
读队列数据;
}
两个进程和两个线程
一般来说,线程,也就是生产者线程和消费者线程在同一个进程/jvm内,就是阻塞队列 + while(true)。
for(true){
阻塞读阻塞队列数据;
}
当然,写也一样,阻塞写阻塞队列数据。
但是,如果是两个进程,生产者进程和消费者进程。那么就是定时任务 + 非阻塞队列 + while(队列大小)。
也就是说,是通过定时任务,来实现不停的处理数据的功能的。而两个线程是通过while(true),来实现不停的处理新到来的数据。
参考
这些文章都很简单,仅供参考