Java并发编程系列文章收集在我的Github-Java后端成长路线中
https://github.com/geekibli/java-study
Blocking Queue
A blocking queue is a queue that blocks when you try to dequeue from it and the queue is empty, or if you try to enqueue items to it and the queue is already full. A thread trying to dequeue from an empty queue is blocked until some other thread inserts an item into the queue. A thread trying to enqueue an item in a full queue is blocked until some other thread makes space in the queue, either by dequeuing one or more items or clearing the queue completely.
阻塞队列两大特性:
- 当队列满时,如果生产者线程向队列 put 元素,队列会一直阻塞生产者线程,直到队列可用或者响应中断退出
- 当队列为空时,如果消费者线程 从队列里面 take 元素,队列会阻塞消费者线程,直到队列不为空
阻塞队列最常使用在生产者和消费者模型中,生产者生产数据,将数据存放在队列中,消费者消费数据,在队列中取出数据。
阻塞队列在不可用时,下面是各种处理操作的结果:👇
方法/处理方式 | 抛出异常 | 返回特殊值 | 一直阻塞 | 超时退出 |
---|---|---|---|---|
插入方法 | add(e) | offer(e) | put(e) | offer(e, time,unit) |
移除方法 | remove() | poll() | take() | poll(time,unit) |
检查方法 | element() | peek() | 不可用 | 不可用 |
add 抛出异常IllegalStateException
public class ArrayBlockingQueueDemo {
public static void main(String[] args) {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
queue.add("a");
queue.add("b");
System.err.println("queue size -> " + queue.size());
}
}
异常信息:
Exception in thread "main" java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(AbstractQueue.java:98)
at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
at com.ibli.note.ArrayBlockingQueueDemo.main(ArrayBlockingQueueDemo.java:15)
element抛出异常NoSuchElementException
public class ArrayBlockingQueueDemo {
public static void main(String[] args) {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
System.err.println("queue size -> " + queue.size());
queue.element();
}
}
异常信息:
queue size -> 0
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractQueue.element(AbstractQueue.java:136)
at com.ibli.note.ArrayBlockingQueueDemo.main(ArrayBlockingQueueDemo.java:14)
ArrayBlockingQueue
底层由数组实现的有界的阻塞队列,它的容量在创建的时候就已经确认了,并且不能修改。
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(f