阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
阻塞队列提供了四种处理方法:
方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出
插入方法 add(e) offer(e) put(e) offer(e,time,unit)
移除方法 remove() poll() take() poll(time,unit)
检查方法 element() peek() 不可用 不可用
抛出异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException(“Queue full”)异常。当队列为空时,从队列里获取元素时会抛出NoSuchElementException异常 。
返回特殊值:插入方法会返回是否成功,成功则返回true。移除方法,则是从队列里拿出一个元素,如果没有则返回null
一直阻塞:当阻塞队列满时,如果生产者线程往队列里put元素,队列会一直阻塞生产者线程,直到拿到数据,或者响应中断退出。当队列空时,消费者线程试图从队列里take元素,队列也会阻塞消费者线程,直到队列可用。
超时退出:当阻塞队列满时,队列会阻塞生产者线程一段时间,如果超过一定的时间,生产者线程就会退出。
- Java里的阻塞队列
JDK7提供了7个阻塞队列。分别是
ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
DelayQueue:一个使用优先级队列实现的无界阻塞队列。
SynchronousQueue:一个不存储元素的阻塞队列。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
简单理解:
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:
线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素
从5.0开始,JDK在java.util.concurrent包里提供了阻塞队列的官方实现。尽管JDK中已经包含了阻塞队列的官方实现,但是熟悉其背后的原理还是很有帮助的。
package thread.BlockingQueue;
import sun.awt.CustomCursor;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class BlockingQueueTest {
/**
* 生产者
*/
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);
//创建5个生产者,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
即可看到生产者生产的 被消费者消费了,与普通队列不同的是
队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来