由于阻塞式队列主要实现入队列和出队列操作,因此我们可以用阻塞式队列实现生产者消费者模型。
生产者消费者模型:
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而
通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者
要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队
列就是用来给生产者和消费者解耦的。
我们定义了两个生产者,每个生产者生产5个;定义两个消费者,每个消费者消费5个。
import java.util.*;
public class MyBlockingQueue<E> {
//队列元素
private Object[] elements;
//添加元素时的位置
private int addIndex;
//取出元素时的位置
private int takeIndex;
//队列大小,数组具体使用到了位置的下标
private int size;
// 构造方法初始化阻塞队列的容量
public MyBlockingQueue(int range) {
elements = new Object[range];
}
// 取元素
public synchronized E pull() {
E element = null;
try {
while (size == 0) {
wait();
}
element = (E) elements[takeIndex];
takeIndex = (takeIndex + 1) % elements.length;
size--;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
return element;
}
// 存元素
public synchronized void offer(E element) {
try {
while (size == elements.length) {
wait();
}
elements[addIndex] = element;
addIndex = (addIndex + 1) % elements.length;
size++;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static volatile int COUNT;
public static void main(String[] args) {
MyBlockingQueue myBlockingQueue = new MyBlockingQueue(10);
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 5; j++) {
int num = new Random().nextInt(100) + 1;
synchronized (myBlockingQueue) {
COUNT++;
System.out.println(num + "存" + COUNT);
myBlockingQueue.offer(num);
}
}
}
}).start();
}
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 5; j++) {
synchronized (myBlockingQueue) {
COUNT++;
System.out.println(myBlockingQueue.pull() + "取" + COUNT);
}
}
}
}).start();
}
}
}