一個隊列在隊空和隊滿的狀況下進行出隊和進隊操做會發生阻塞,這種隊列咱們稱之爲阻塞隊列.隊列在隊空的狀況下進行出隊操做會發生阻塞,直到有一到多個隊項入隊爲止.隊列在隊滿的狀況下入隊會發生阻塞,直到有隊項出列或隊空的狀況下.html
這是一個兩個線程經過阻塞隊列協做的示例圖:java
咱們能夠看出一個線程從隊列中取出隊項,一個線程往隊列中放入對項.post
Java5的java.util.concurrent
包中已有現成的阻塞隊列實現.但咱們仍然頗有必要知道它的底層實現原理.this
一個阻塞隊列的實現看起來有點像BoundedSemaphore.以下一個簡單的阻塞隊列實現:spa
public class BlockingQueue<T> {
private List<T> queue = new ArrayList<>();
private int limit = 10;
public BlockingQueue(int limit) {
this.limit = limit;
}
public synchronized void enqueue(T item) {
while (queue.size() == limit) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (queue.size() == 0) {
notifyAll();
}
queue.add(item);
}
public synchronized T dequeue(){
while (queue.size() == 0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(queue.size() == limit){
notifyAll();
}
return queue.remove(0);
}
}
複製代碼
咱們能夠注意到當調用enqueue()和dequeue()發現隊滿和隊空時須要調用notifyAll()來喚醒相應的線程來取出和放入隊項.若是隊列大小沒有達到限制,那麼兩個線程能夠在不用阻塞線程的狀況下放入和取出隊項.線程
該系列博文爲筆者複習基礎所著譯文或理解後的產物,複習原文來自Jakob Jenkov所著Java Concurrency and Multithreading Tutorial code