文章目录
1. 概述2. 常用的阻塞队列3. 操作方法3.1 抛出异常3.2 特殊值3.3 阻塞3.4 超时
1. 概述
相比平时讨论的队列,阻塞队列增加了阻塞的功能:
当有限长度的队列填满了数据时,继续往队列添加数据的线程将被阻塞住,持续等待,直到超时或队列数据被消费而腾出空间当队列数据为空时,消费线程会因为取不到数据而被阻塞,直到生产线程往队列添加数据,此时成功取到数据而不再阻塞
2. 常用的阻塞队列
ArrayBlockingQueue:由数组结构组成的有界阻塞队列,底层的出入队由同一个ReentrantLock加锁控制,可以传递fair参数指定使用公平锁 or 非公平锁LinkedBlockingQueue:由链表结构组成的有界阻塞队列(容量默认是Integer.MAX_VALUE,因此也可以理解成无界)。其出入队由不同的ReentrantLock控制,因此性能优于ArrayBlockingQueueSynchronousQueue:只存储一个元素的阻塞队列,容量大小只有1
3. 操作方法
方法类型抛出异常特殊值阻塞超时
添加add(e)offer(e)put()offer(e,time,unit)移除remove()poll()take()poll(time,unit)获取element()peek()——
3.1 抛出异常
以下情况将直接抛出异常:
队列满了,调用 add()队列为空,调用 remove()队列为空,调用 element()
BlockingQueue
<String> queue
= new ArrayBlockingQueue<>(3);
queue
.add("a");
queue
.add("b");
queue
.add("c");
queue
.add("d");
3.2 特殊值
队列满了,调用 offer(),将返回false,否则返回true队列为空,调用 poll(),将返回false,否则返回true队列为空,调用 peek(),将返回null,否则返回队列元素
BlockingQueue
<String> queue
= new ArrayBlockingQueue<>(3);
System
.out
.println(queue
.offer("a"));
System
.out
.println(queue
.offer("b"));
System
.out
.println(queue
.offer("c"));
System
.out
.println(queue
.offer("d"));
3.3 阻塞
队列满了,调用 put(),线程将被阻塞队列为空,调用take(),线程将被阻塞
BlockingQueue
<String> queue
= new ArrayBlockingQueue<>(3);
new Thread(() -> {
for (int i
= 1; i
<= 4; i
++){
String elem
= "a" + i
;
try {
queue
.put(elem
);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
System
.out
.println(Thread
.currentThread().getName() + "添加元素:" + elem
);
}
}, "Thread-1").start();
Thread
.sleep(3000);
new Thread(() -> {
System
.out
.println(Thread
.currentThread().getName() + "移除了一个元素");
try {
queue
.take();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}, "Thread-2").start();
输出如下:
Thread-1添加元素:a1
Thread-1添加元素:a2
Thread-1添加元素:a3
Thread-2移除了一个元素
Thread-1添加元素:a4
3.4 超时
超时方法是 3.2特殊值 的升级版,只是参数加了个超时时间。执行失败的时候不会直接返回false,而是会等待一段时间,如果在时间到期前操作成功会返回true,否则才返回false。
BlockingQueue
<String> queue
= new ArrayBlockingQueue<>(3);
for (int i
= 1; i
<= 4; i
++){
String elem
= "a" + i
;
boolean result
= queue
.offer(elem
, 5, TimeUnit
.SECONDS
);
System
.out
.println(new Date() + "---->" + Thread
.currentThread().getName() + "添加数据:" + elem
+ ",结果:" + result
);
}
输出如下,最后一个false间隔了5秒才返回
Wed Oct 21 14:28:33 CST 2020----
>main添加数据:a1,结果:true
Wed Oct 21 14:28:33 CST 2020----
>main添加数据:a2,结果:true
Wed Oct 21 14:28:33 CST 2020----
>main添加数据:a3,结果:true
Wed Oct 21 14:28:38 CST 2020----
>main添加数据:a4,结果:false