Producer-ConsumerPattern
Producer是“生产者”的意思,是指产生数据的线程。而Consumer是“消费者”的意思,意指使用数据的线程。
生产者必须将数据安全地交给消费者。虽然只是这样的问题,但当生产者与消费者在不同线程上运行时,两者的处理速度差将是最大的问题。当消费者要取数据时生产者还没建立出数据,或是生产者建立出数据时消费者的状态还没办法接收数据等等。
Producer-ConsumerPattern是在生产者与消费者之间加入一个“桥梁参与者”。以这个桥梁参与者与缓冲线程之间的处理速度差。
范例程序
Main 操作测试用的类
Producer模拟生产者生产数据
Consumer模拟消费者使用数据
DataNumber产生数据编号
Buffer模拟缓冲区
Buffer代码:
public class Buffer {
private String[] buffer;// 模拟缓冲区
private int count;// 缓冲区中数据的个数
private int head;// 下一个取走数据的地方
private int tail;// 下一个放置数据的地方
public Buffer(int size) {
buffer = new String[size];
count = 0;
head = 0;
tail = 0;
}
public synchronized void put(String data)throws InterruptedException {
while (count >= buffer.length) {
wait();
}
buffer[tail] = data;
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+ " 放入数据: " + data);
tail = (tail + 1) % buffer.length;
count++;
notifyAll();
}
public synchronized String get() throwsInterruptedException {
while (count <= 0) {
wait();
}
String data = buffer[head];
head = (head + 1) % buffer.length;
count--;
notifyAll();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+ " 取出数据: " + data);
return data;
}
}
DataNumber代码:
public final classDataNumber {
private static int number = 1;
public synchronized static int getNumber() {
return number++;
}
}
Producer代码:
public class Producerextends Thread {
private Buffer buffer;
public Producer(Buffer buffer, StringthreadName) {
super(threadName);
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
String data = "Data No."
+String.valueOf(DataNumber.getNumber());
buffer.put(data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Consumer代码:
public class Consumerextends Thread {
private Buffer buffer;
public Consumer(Buffer buffer, StringthreadName) {
super(threadName);
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
buffer.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Main代码:
public class Main {
/**
*@param args
*/
public static void main(String[] args) {
Buffer buffer = new Buffer(5);
new Producer(buffer,"Producer1").start();
new Producer(buffer,"Producer2").start();
new Producer(buffer,"Producer3").start();
new Consumer(buffer,"Consumer1").start();
new Consumer(buffer,"Consumer2").start();
}
}
从运行结果可以看出:消费者按生产者放入数据的顺序从缓冲区中取出数据。
要以什么顺序传递Data
Ø 队列——最先收到的先传
最常见的做法,是把最先收到的传出去。我们将这种方法称为FIFO(First In First Out),先进先出或称为队列(Queue)。
Ø 堆栈——最后收到的先传
与队列相反的,最后收到的Data先传出去。这称之为LIFO(Last In First Out),后进先出,又称为堆栈(stack)。
Ø 优先队列——“优先”的东西先传
对Data以某些条件给予优先次序,而优先性高的先传给Consumer参与者。决定优先次序的方法有很多,依应用情况而定。
队列、堆栈可以说是优先队列的特例,Data收到时间较早、优先性高的优先队列称为队列,而Data收到时间较晚、优先性高的优先队列称为堆栈。