这个模式跟Guarded模式有点类似,不过需要一个控制台限制请求方和处理方的频度和数量。
public class ProducerConsumerTest { /** * @param args */ public static void main(String[] args) { Table table = new Table(3); new MakerThread("MakerThread1", table , 1000).start(); new MakerThread("MakerThread2", table , 1000).start(); new MakerThread("MakerThread3", table , 1000).start(); new TakerThread("TakerThread1", table , 1000).start(); new TakerThread("TakerThread2", table , 1000).start(); new TakerThread("TakerThread3", table , 1000).start(); } } class MakerThread extends Thread{ private final Random random; private final Table table; private static int id=0; public MakerThread(String name, Table table, long seed){ super(name); this.table=table; this.random = new Random(seed); } @Override public void run() { try{ while(true){ Thread.sleep(random.nextInt(1000)); String cake = "[cake no. " + nextId() + ", by " + getName() + "]"; table.put(cake); } }catch(InterruptedException e){ e.printStackTrace(); } } public static synchronized int nextId(){ return id++; } } class TakerThread extends Thread{ private final Random random; private final Table table; public TakerThread(String name, Table table, long seed){ super(name); this.table =table; this.random = new Random(seed); } @Override public void run() { try{ while(true){ String cake = table.take(); Thread.sleep(random.nextInt(1000)); } }catch(InterruptedException e){ e.printStackTrace(); } } } class Table{ private final String[] buffer; private int tail; private int head; private int count; public Table(int count){ buffer = new String[count]; this.head=0; this.tail=0; this.count=0; } public synchronized void put(String cake) { System.out.println(Thread.currentThread().getName() + " puts " + cake); while (count >= buffer.length) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } buffer[tail] = cake; tail = (tail + 1) % buffer.length; count++; notify(); } public synchronized String take() { while (count <= 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } String cake = buffer[head]; head = (head + 1) % buffer.length; count--; notify(); System.out.println(Thread.currentThread().getName() + " take " + cake); return cake; } }