多线程设计模式之——Producer-Consumer Pattern
程序员文章站
2022-07-09 09:01:12
...
此模式是在生产者与消费者之间加入一个“桥梁参与者”来缓冲线程之间的处理速度差。一般可以存在多个生产者与消费者,但当双方都只有一个的时候,又称为Pipe Pattern。
例子:假设有2个生产者,2个消费者,仓库里只能放4个产品。(这里的产品就是String类型的名字而已)
例子:假设有2个生产者,2个消费者,仓库里只能放4个产品。(这里的产品就是String类型的名字而已)
//Storage.java public class Storage { private String[] buffer; private int head;//取走一个商品的位置 private int tail;//存入一个商品的位置 private int count;//buffer内的商品数量 public Storage(int count){ this.buffer = new String[count]; this.count = 0; this.head = 0; this.tail = 0; } //这里的if警戒条件就运用了Guarded Suspension Pattern,要求不满足条件,便等待 public synchronized void put(String goods) throws InterruptedException{ System.out.println(Thread.currentThread().getName() + " produce the goods:" + goods); if(count >= buffer.length){ System.out.println("the storage is full!"); wait(); } buffer[tail] = goods; tail = (tail + 1) % buffer.length; count++; notifyAll(); } public synchronized String get() throws InterruptedException{ if(count <= 0){ System.out.println("the storage is empty!"); wait(); } String goods = buffer[head]; head = (head + 1) % buffer.length; count--; notifyAll(); System.out.println(Thread.currentThread().getName() + " consume the goods:" + goods ); return goods; } }
//ProducerThread.java import java.util.Random; public class ProducerThread extends Thread { private Storage storage; private Random random; private static int pid; //产品编号 public ProducerThread(String name , Storage storage){ super(name); this.storage = storage; this.random = new Random(); } public void run(){ try{ for(int i=0; i<10; i++){ Thread.sleep(random.nextInt(1000));//模拟生产时间 String goods = getName() + " produce the goods" + nextPId(); storage.put(goods); } }catch(InterruptedException e){ e.printStackTrace(); } } private static synchronized int nextPId(){ return pid++; } }
//ConsumerThread.java import java.util.Random; public class ConsumerThread extends Thread { private Storage storage; private Random random; public ConsumerThread(String name , Storage storage){ super(name); this.random = new Random(); this.storage = storage; } public void run(){ try{ while(true){ storage.get(); Thread.sleep(random.nextInt(2000));//模拟商品使用时间 } }catch(InterruptedException e){ e.printStackTrace(); } } }
//Main.java public class Main { public static void main(String[] args) { Storage storage = new Storage(4); new ProducerThread("producer_lulu01" , storage).start(); new ProducerThread("producer_lulu02" , storage).start(); new ConsumerThread("consumer_fang01" , storage).start(); new ConsumerThread("consumer_fang02" , storage).start(); } }