这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战」
阻塞队列
队列先进先出FIFO。
存入时,如果队列满了,阻塞等待空出。
取出时,如果队列为空,阻塞等待生产。
Collection接口 -> queue接口 -> BlockingQueue接口 queue 下还有一个相反的接口AbstractQueue(非阻塞队列)
源码,add时会判断插入的元素是否为空,然后lock加锁判断
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
remove:可以指定想要抛出的值,如果有就溢出,没有找到就不移除。
public boolean remove(Object o) {
if (o == null) return false;
final Object[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count > 0) {
final int putIndex = this.putIndex;
int i = takeIndex;
do {
if (o.equals(items[i])) {
removeAt(i);
return true;
}
if (++i == items.length)
i = 0;
} while (i != putIndex);
}
return false;
} finally {
lock.unlock();
}
}
抛出异常
// 设置队列的长度为3
ArrayBlockingQueue< Object > objects = new ArrayBlockingQueue<>(3);
boolean add1 = objects.add("1");
boolean add2 = objects.add(1);
boolean add3 = objects.add(new BlockQueue());
boolean add4 = objects.add(1);
System.out.println(add1);
System.out.println(add2);
System.out.println(add3);
- add :插入
- remove : 移除
- element:获取队首元素
queue full:前三个为true,当插入第四个时add() ,超出队列的长度,就会抛出异常
NoSuchElementException:1.当列队为空,还执行remove时,会抛出异常 2.队列为空,执行获取队首操作element()
不抛出异常
- offer : 插入
- poll : 移除
- pick:获取队首元素
boolean add1 = objects.offer("1");
boolean add2 = objects.offer(2);
boolean add3 = objects.offer(3);
// 当队列已满,不会插入,返回false
boolean add4 = objects.offer(4);
objects.poll();
objects.poll();
Object poll1 = objects.poll();
// 当队列已空,不会再移除,返回null
Object poll = objects.poll();
阻塞
- put:插入 ,如果队列已满,会一直等待直到队列不慢
- take: 移除,如果队列已空,会一直等待直到队列中有新的元素
阻塞超时
- offer : 插入,并指定阻塞时间。当队列已满时,会等待timeout的时间,如果这段时间内还是满的,就会插入失败,返回false
- poll : 移除,并指定阻塞时间。当队列为空时,会等待timeout时间。如果该段时间内还是空的,就移除失败,返回false
ArrayBlockingQueue< Object > objects = new ArrayBlockingQueue<>(3);
boolean offer = objects.offer(1, 2, TimeUnit.SECONDS);
System.out.println(offer);
boolean offer2 = objects.offer(2, 2, TimeUnit.SECONDS);
System.out.println(offer2);
boolean offer3 = objects.offer(3, 10, TimeUnit.SECONDS);
System.out.println(offer3);
// 当队列已满时,会等待timeout的时间,如果这段时间内还是满的,就会插入失败,返回false
boolean offer4 = objects.offer(3, 2, TimeUnit.SECONDS);
System.out.println(offer4);
Object poll = objects.poll(2, TimeUnit.SECONDS);
System.out.println(poll);
Object poll1 = objects.poll(2, TimeUnit.SECONDS);
System.out.println(poll1);
Object poll2 = objects.poll(2, TimeUnit.SECONDS);
System.out.println(poll2);
// 当队列为空时,会等待timeout时间。如果该段时间内还是空的,就移除失败,返回false
Object poll3 = objects.poll(2, TimeUnit.SECONDS);
System.out.println(poll3);