Producer - Consumer Pattern 就是生产者 - 消费者模式。
生产者和消费者在为不同处理线程,生产者必须将数据安全地交给消费者,消费者进行消费时,如果生产者还没有建立数据,则消费者需要等待。
一般来说,可能存在多个生产者和消费者,不过也有可能生产者和消费者都只有一个,当双方都只有一个时,我们也称之为Pipe Pattern。
该案例中,定义了3个角色:厨师、客人、桌子。
厨师(生产者)定义:
package Entity; import java.util.Random; public 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() { while (true) { try { Thread.sleep(random.nextInt(1000)); String cake = "[ Cake No." + nextId() + " by " + " ]"; table.put(cake); } catch (InterruptedException e) { e.printStackTrace(); } } } private static synchronized int nextId() { return id++; } }客人(消费者)定义:
package Entity; import java.util.Random; public class EaterThread extends Thread { private Random random; private Table table; public EaterThread(String name, Table table, long seed) { super(name); this.table = table; random = new Random(seed); } @Override public void run() { while (true) { String cake = table.take(); try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }桌子(队列)定义:
package Entity; public class Table { private final String[] buffer; private int tail; private int head; private int count; public Table(int count) { buffer = new String[count]; tail = 0; head = 0; count = 0; } public synchronized void put(String cake) throws InterruptedException { System.out.println(Thread.currentThread().getName() + " puts" + cake); 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() + " takes " + cake); return cake; } }执行:
import Entity.EaterThread; import Entity.MakerThread; import Entity.Table; public class Demo5 { public static void main(String[] args) { Table table = new Table(3); new MakerThread("MakerThread-1",table,31415).start(); new MakerThread("MakerThread-2",table,92653).start(); new MakerThread("MakerThread-3",table,58979).start(); new EaterThread("EaterThread-1",table,32384).start(); new EaterThread("EaterThread-2",table,62643).start(); new EaterThread("EaterThread-3",table,38327).start(); } }Producer - Consumer模式的角色如下:
Data(数据)参与者Data代表了实际生产或消费的数据
Producer(生产者)参与者Producer会创建Data,然后传递给Channel参与者
Consumer(消费者)参与者Consumer从Channel参与者获取Data数据,进行处理。
Channel(通道)参与者Channel从Producer参与者处接受Data参与者,并保管起来,并应Consumer参与者的要求,将Data参与者传送出去。为确保安全性,Producer参与者与Consumer参与者要对访问共享互斥。