阻塞隊列(BlockingQueue)是一個支持兩個附加操作的隊列。這兩個附加的操作是:在隊列為空時,獲取元素的線程會等待隊列變?yōu)榉强?。當隊列滿時,存儲元素的線程會等待隊列可用。阻塞隊列常用于生產(chǎn)者和消費者的場景,生產(chǎn)者是往隊列里添加元素的線程,消費者是從隊列里拿元素的線程。阻塞隊列就是生產(chǎn)者存放元素的容器,而消費者也只從容器里拿元素。
阻塞隊列提供了四種處理方法:
方法\處理方式 拋出異常 返回特殊值 一直阻塞 超時退出
插入方法 add(e) offer(e) put(e) offer(e,time,unit)
移除方法 remove() poll() take() poll(time,unit)
檢查方法 element() peek() 不可用 不可用
拋出異常:是指當阻塞隊列滿時候,再往隊列里插入元素,會拋出IllegalStateException(“Queue full”)異常。當隊列為空時,從隊列里獲取元素時會拋出NoSuchElementException異常 。
返回特殊值:插入方法會返回是否成功,成功則返回true。移除方法,則是從隊列里拿出一個元素,如果沒有則返回null
一直阻塞:當阻塞隊列滿時,如果生產(chǎn)者線程往隊列里put元素,隊列會一直阻塞生產(chǎn)者線程,直到拿到數(shù)據(jù),或者響應中斷退出。當隊列空時,消費者線程試圖從隊列里take元素,隊列也會阻塞消費者線程,直到隊列可用。
超時退出:當阻塞隊列滿時,隊列會阻塞生產(chǎn)者線程一段時間,如果超過一定的時間,生產(chǎn)者線程就會退出。
- Java里的阻塞隊列
JDK7提供了7個阻塞隊列。分別是
ArrayBlockingQueue :一個由數(shù)組結構組成的有界阻塞隊列。
LinkedBlockingQueue :一個由鏈表結構組成的有界阻塞隊列。
PriorityBlockingQueue :一個支持優(yōu)先級排序的無界阻塞隊列。
DelayQueue:一個使用優(yōu)先級隊列實現(xiàn)的無界阻塞隊列。
SynchronousQueue:一個不存儲元素的阻塞隊列。
LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。
LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。
簡單理解:
阻塞隊列與普通隊列的區(qū)別在于,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列,下圖展示了如何通過阻塞隊列來合作:
線程1往阻塞隊列中添加元素,而線程2從阻塞隊列中移除元素
從5.0開始,JDK在java.util.concurrent包里提供了阻塞隊列的官方實現(xiàn)。盡管JDK中已經(jīng)包含了阻塞隊列的官方實現(xiàn),但是熟悉其背后的原理還是很有幫助的。
package thread.BlockingQueue;
import sun.awt.CustomCursor;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class BlockingQueueTest {
/**
* 生產(chǎn)者
*/
public static class Producer implements Runnable{
private final BlockingQueue<Integer> blockingQueue;
//同步變量 volatile
private volatile boolean flag;
private Random random;
public Producer(BlockingQueue<Integer> blockingQueue){
this.blockingQueue = blockingQueue;
flag=false;
random=new Random();
}
@Override
public void run() {
while (!flag){
int info = random.nextInt();
try {
blockingQueue.put(info);
System.out.println(Thread.currentThread().getName()+"---->Producer"+info);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutDown(){
flag = true;
}
}
public static class Consumer implements Runnable{
private final BlockingQueue<Integer> blockingQueue;
private volatile boolean flag;
public Consumer(BlockingQueue<Integer> blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!flag){
int info;
try {
info = blockingQueue.take();
System.out.println(Thread.currentThread().getName()+" --->consumer "+info);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutDown(){
flag=true;
}
public static void main(String[] args) {
BlockingQueue<Integer> blockingQueue = new LinkedBlockingDeque<Integer>(10);
Producer producer = new Producer(blockingQueue);
Consumer consumer = new Consumer(blockingQueue);
//創(chuàng)建5個生產(chǎn)者,5個消費者
for(int i = 0; i<10;i++){
//System.out.println("-----------------------"+i+"-----------------------");
if(i<5){
new Thread(producer,"producer"+i).start();
}else{
new Thread(consumer,"consumer"+(i-5)).start();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
producer.shutDown();
consumer.shutDown();
}
}
}
輸出
producer0---->Producer-1129494571
producer1---->Producer1335810196
producer2---->Producer251379931
producer3---->Producer-1038309758
producer4---->Producer1259289873
consumer0 --->consumer -1129494571
consumer1 --->consumer 1335810196
consumer2 --->consumer 251379931
consumer3 --->consumer -1038309758
consumer4 --->consumer 1259289873
producer0---->Producer2080589140
producer1---->Producer-226440319
producer3---->Producer-1251256190
producer2---->Producer1570622388
producer4---->Producer-1730471428
consumer1 --->consumer 2080589140
consumer0 --->consumer -226440319
consumer2 --->consumer -1251256190
consumer3 --->consumer 1570622388
consumer4 --->consumer -1730471428
producer1---->Producer-1117165496
producer0---->Producer1429895528
producer4---->Producer-12279844
producer2---->Producer1148382323
producer3---->Producer859079924
consumer0 --->consumer -1117165496
consumer1 --->consumer 1429895528
consumer2 --->consumer -12279844
consumer3 --->consumer 1148382323
consumer4 --->consumer 859079924
producer0---->Producer697920454
producer1---->Producer-1472263430
producer3---->Producer1862992273
producer2---->Producer-431825769
producer4---->Producer-170876869
consumer0 --->consumer -1472263430
consumer1 --->consumer 697920454
consumer2 --->consumer 1862992273
consumer3 --->consumer -431825769
consumer4 --->consumer -170876869
producer0---->Producer661728231
producer1---->Producer-1580613248
producer4---->Producer286944580
producer2---->Producer-1756199503
producer3---->Producer-515489831
consumer1 --->consumer 661728231
consumer0 --->consumer -1580613248
consumer3 --->consumer 286944580
consumer2 --->consumer -1756199503
consumer4 --->consumer -515489831
producer0---->Producer-824253958
producer1---->Producer-718043703
producer2---->Producer613726687
producer4---->Producer1562017654
producer3---->Producer2113604249
consumer3 --->consumer -718043703
consumer0 --->consumer -824253958
consumer1 --->consumer 613726687
consumer2 --->consumer 2113604249
consumer4 --->consumer 1562017654
producer1---->Producer-1926369295
producer0---->Producer1160592917
producer3---->Producer261832181
producer4---->Producer45296507
producer2---->Producer2027140406
consumer3 --->consumer -1926369295
consumer1 --->consumer 1160592917
consumer2 --->consumer 261832181
consumer0 --->consumer 45296507
consumer4 --->consumer 2027140406
producer1---->Producer268940344
producer0---->Producer-680320907
producer3---->Producer1376218456
producer4---->Producer-1303516038
producer2---->Producer-415045622
consumer3 --->consumer -680320907
consumer2 --->consumer 268940344
consumer1 --->consumer 1376218456
consumer0 --->consumer -1303516038
consumer4 --->consumer -415045622
producer1---->Producer-373379865
producer0---->Producer1045950051
producer3---->Producer-282195419
producer4---->Producer2072455342
producer2---->Producer730482583
consumer3 --->consumer 1045950051
consumer0 --->consumer -373379865
consumer1 --->consumer -282195419
consumer2 --->consumer 2072455342
consumer4 --->consumer 730482583
producer0---->Producer1099300076
producer1---->Producer-438856015
producer3---->Producer-827705749
producer4---->Producer-489876804
producer2---->Producer-770066015
consumer3 --->consumer 1099300076
consumer2 --->consumer -438856015
consumer0 --->consumer -489876804
consumer1 --->consumer -827705749
consumer4 --->consumer -770066015
producer3---->Producer796772527
producer4---->Producer-1424401866
producer1---->Producer2104464948
producer0---->Producer-843892940
producer2---->Producer167062848
consumer3 --->consumer -1424401866
consumer1 --->consumer 796772527
consumer0 --->consumer 2104464948
consumer2 --->consumer -843892940
consumer4 --->consumer 167062848
producer0---->Producer2062676055
producer1---->Producer-1075270028
producer4---->Producer830173242
producer3---->Producer-288128280
producer2---->Producer-1316693459
consumer3 --->consumer 2062676055
consumer2 --->consumer -1075270028
consumer1 --->consumer -1316693459
consumer0 --->consumer 830173242
consumer4 --->consumer -288128280
producer0---->Producer-1740245319
producer1---->Producer-2079049898
producer4---->Producer-1382219742
producer3---->Producer663598513
producer2---->Producer-1374412157
consumer3 --->consumer -1740245319
consumer4 --->consumer -2079049898
consumer0 --->consumer -1382219742
consumer1 --->consumer 663598513
consumer2 --->consumer -1374412157
producer3---->Producer923120722
producer4---->Producer1267254300
producer2---->Producer-355170922
producer0---->Producer-384775396
producer1---->Producer1978595907
consumer4 --->consumer -355170922
consumer3 --->consumer 923120722
consumer2 --->consumer 1267254300
consumer1 --->consumer 1978595907
consumer0 --->consumer -384775396
producer4---->Producer301647653
producer3---->Producer2070336417
consumer4 --->consumer 301647653
consumer3 --->consumer 2070336417
producer1---->Producer130543442
producer0---->Producer33891840
producer2---->Producer199012254
consumer2 --->consumer 130543442
consumer1 --->consumer 33891840
consumer0 --->consumer 199012254
producer4---->Producer2034412277
consumer3 --->consumer 2034412277
consumer4 --->consumer 1684896549
producer3---->Producer1684896549
producer2---->Producer-823024779
producer0---->Producer1245530223
producer1---->Producer1426270482
consumer2 --->consumer -823024779
consumer1 --->consumer 1245530223
consumer0 --->consumer 1426270482
consumer3 --->consumer -657670721
producer4---->Producer-657670721
consumer0 --->consumer -514396374
producer1---->Producer-514396374
consumer1 --->consumer -1938139766
producer0---->Producer-1938139766
consumer2 --->consumer -1416028874
producer2---->Producer-1416028874
producer3---->Producer386535270
consumer4 --->consumer 386535270
producer4---->Producer-280750862
consumer3 --->consumer -280750862
producer0---->Producer-1610461450
consumer1 --->consumer -1610461450
producer1---->Producer-906749135
consumer0 --->consumer -906749135
consumer4 --->consumer -1239123559
producer3---->Producer-1239123559
producer2---->Producer596392102
consumer2 --->consumer 596392102
producer4---->Producer144344294
consumer3 --->consumer 144344294
producer2---->Producer-239480864
consumer2 --->consumer -239480864
producer3---->Producer-1952232640
consumer4 --->consumer -1952232640
consumer0 --->consumer -138057655
producer1---->Producer-138057655
consumer1 --->consumer -1277497082
producer0---->Producer-1277497082
Process finished with exit code 0
即可看到生產(chǎn)者生產(chǎn)的 被消費者消費了,與普通隊列不同的是
隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來