Producer-Consumer
很多时候生产者消费者速度不一致且差距比较大的情况下:生产者和消费者多线程设计模式,就可以考虑一下了。最关键的就是中间有一个缓冲的桥梁。(桥梁有两个限制,一个是装不下的情况,一个是取不出的情况)
//生产者代码public class MakerThread extends Thread { private final Table table; private static int id = 0; public MakerThread(String name, Table table) { super(name); this.table = table; } public void run() { try { while (true) { Thread.sleep(500); String cake = "no." + nextId(); table.put(cake); } } catch (InterruptedException e) { } } public synchronized int nextId() { return id++; }}
//消费者代码public class EaterThread extends Thread { private final Table table; public EaterThread(String name, Table table) { super(name); this.table = table; } public void run() { try { while (true) { String cake = table.take(); Thread.sleep(1000); } } catch (InterruptedException e) { } }}
//中间的桥梁public class Table { private final String [] buffer; private int tail; private int head; private int count; public Table(int count) { this.buffer=new String [count]; this.head=0; this.tail=0; this.count=0; } //放不进的考虑 public synchronized void put(String cake) throws InterruptedException{ System.out.println(Thread.currentThread().getName()+" puts "+cake+" "+count); while(count>=buffer.length){ wait(); } buffer[tail]=cake; tail=(tail+1)%buffer.length; count++; notifyAll(); } //取不出的情况要有考虑 public synchronized String take() throws InterruptedException{ while(count<=0){ wait(); } String cake=buffer[head]; head=(head+1)%buffer.length; count--; notifyAll(); System.out.println(Thread.currentThread().getName()+"take"+cake); return cake; } }
最负责的部分就是对桥梁的封装设计,对与每一个线程的操作都要一致,如何保证的情况下,就是考虑两种情况的同时,保证只有一个线程修改临界区(感觉已经有read-write的一点共同点,但没有抓住关键点)。