對於生產者消費者模型,如果我們採用常規的容器,那麼我們需要同步,並且需要在生產者線程和消費者線程之間做wait和notify的線程間通信。而阻塞隊列將同步操作和生產者和消費者間的通信在容器內部實現,使用起來就不需要我們自己做同步和線程通信了。
Java中提供的BlockingQueue包括:
ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue。
一個典型的應用場景就是socket客戶端數據的讀取和解析。
另外關於生產者-消費者模型,下面是採用Object.wait(),Object.notify()非阻塞容器實現的生產者-消費者模式:
摘抄自此
public class Test {
private int queueSize = 10;
private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(queueSize);
public static void main(String[] args) {
Test test = new Test();
Producer producer = test.new Producer();
Consumer consumer = test.new Consumer();
producer.start();
consumer.start();
}
class Consumer extends Thread{
@Override
public void run() {
consume();
}
private void consume() {
while(true){
synchronized (queue) {
while(queue.size() == 0){
try {
System.out.println("隊列空,等待數據");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
queue.notify();
}
}
queue.poll(); //每次移走隊首元素
queue.notify();
System.out.println("從隊列取走一個元素,隊列剩餘"+queue.size()+"個元素");
}
}
}
}
class Producer extends Thread{
@Override
public void run() {
produce();
}
private void produce() {
while(true){
synchronized (queue) {
while(queue.size() == queueSize){
try {
System.out.println("隊列滿,等待有空餘空間");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
queue.notify();
}
}
queue.offer(1); //每次插入一個元素
queue.notify();
System.out.println("向隊列取中插入一個元素,隊列剩餘空間:"+(queueSize-queue.size()));
}
}
}
}
}