在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。
单单抽象出生产者和消费者,还够不上是生产者/消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。
因此,可以抽象出生产者-----缓冲区-----消费者这样的基本架构设计。
这个其实在日常生活中可以接触到:你去投递信件,你负责的只是把信件投递到对应的箱子中,这个箱子就类似于一个缓冲区。然后由信件发送员在某个时刻(这个时刻不确定)去箱子中取。信件投递者就是生产者,而箱子就类似于一个缓冲区,信件发送员就类似于一个消费者。
具体代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class ProduceCustomerPattern {
public static void main(String[] args) throws InterruptedException {
List<Good> goods = new ArrayList<Good>();
for(int i = 0 ; i < 10 ; i++){//初始化生产数据
Good good = new Good(i,i);
goods.add(good);
}
System.out.println(s(goods));
}
public static String s(List<Good> goods){
BlockingQueue queue = new LinkedBlockingDeque();
Thread producer = new Thread(new Produce(queue , goods));
Thread customer = new Thread(new Customer(queue));
producer.start();
customer.start();
return "OK";
}
}
class doAdd{
public void doAddGoods(Good good){
System.out.println("ADD==========="+good.toString());
}
public void doDelGoods(Good good){
System.out.println("DELTE======"+good.toString());
}
}
class Good{
private int i ;
private int j;
public Good(int i , int j){
this.i= i;
this.j= j;
}
public String toString(){
return this.i+"===="+j;
}
}
/**
* 生产者
*/
class Produce implements Runnable {
private BlockingQueue queue;
private List<Good> goods;
public Produce(BlockingQueue queue , List<Good> goods ){
this.queue = queue;
this.goods = goods;
}
public void run() {
for(int i = 0 ; i < goods.size() ; i++){
new doAdd().doAddGoods(goods.get(i));
queue.add(this.goods.get(i));
}
}
}
/**
* 消费者
*/
class Customer implements Runnable{
private BlockingQueue queue;
public Customer(BlockingQueue queue){
this.queue = queue;
}
@Override
public void run() {
while(true){
try {
Good good = (Good)queue.take();
new doAdd().doDelGoods(good);
} catch (InterruptedException e) {
//logger.error("", e);
System.out.println("异常");
}
}
}
}