背景
Java queue接口是JDK1.5后才出现的集合, 只要目的是提供一个有优先级顺序的集合操作。 除了包括一些基本的集合操作之外,queue还提供额外的插入, 删除和获取元素的操作。 这三种操作都提供了两种方法, 一种是当操作失败的时候会抛出异常, 另外一种是当操作失败的时候会返回一个特定的值,这个值有可能是null或者 false,取决于操作类型。
throw exception | return special value | Special value |
---|---|---|
add(E e) | offer(E e) | false |
remove() | poll() | null |
element() | peek() | null |
add 和 offer的 区别
add 是用来向queue里插入元素, 返回true如果没有没有超过queue的最大容量, 抛出IllegalStateException 如果queue 已经满了。 offer也还是用来向queue里插入元素, 成功会返回true, queue 满了的话会返回false。 在queue 有规定长度的情况下一般推荐使用offer方法来插入元素
remove 和 poll 的区别
remove 和 poll都是用来删除queue 头部的第一个元素, 不同之处是当queue是空的时候, remove 会抛出NoSuchElementException 异常, 而 poll 会返回一个null。
element 和 peek 的区别
element 和 peek 都是返回queue 的第一个元素, 但是不会删除, 不同之处是当queue是空的时候, element 会抛出NoSuchElementException 异常, 而 peek 会返回一个null。
BlockingQueue 接口
BlockingQueue 扩展了Queue,增加了可阻塞的插入和获取的操作。如果队列是空, 那么获取元素的操作将一直阻塞,直到队列中出现一个可用的原色。如果队列已经满了, 那么插入元素的操作将一直阻塞, 直到队列中出现可用的空间。
BlockingQueue 对于每种操作提供Queue的两种方式外, 还提供了阻塞的两种方式, 一种是无限制的等待满足条件的出现, 另外一种是等待特定的时间间隔。
throw exception | return special value | Blocks indefinitely | Block for time interval |
---|---|---|---|
add(E e) | offer(E e) | put(E e) | offer(e, time, unit) |
remove() | poll() | take() | poll(time, unit) |
element() | peek() | not applicable | not applicable |
值得注意的是BlockingQueue 不允许插入null,否则会抛出NPE。返回结果是null表示poll失败。 BlockingQueue的实现类主要是为了服务生产者-消费者队列的,都是线程安全的,但是如果没有在实现类种特别处理addAll,containsAll 和removeAll操作, 这几种方法都不是原子性的。
典型的BlockingQueue的生产者-消费者使用场景如下
'''
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue queue){
this.queue = queue;
}
@Override
public void run() {
while (true){
try {
queue.put(produce());
}catch (InterruptedException e){
// handle exception
}
}
}
Object produce(){
// produce;
}
}
class Consumer implements Runnable {
private final BlockingQueue queue;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while (true){
try{
queue.take(consume());
}catch (InterruptedException e){
//handle exception
}
}
}
void consume(){
// consume
}
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
'''
LinkedBlockingQueue, ArrayBlockingQueue 和 PriorityBlockingQueue
在集合框架中,有BlockingQueue的多种实现,其中LinkedBlockingQueue 和 ArrayBlockingQueue 是FIFO队列,二者分别与LinkedList和ArrayList 类似,但是比同步list有更好的并发性能。PriorityBlockingQueue是一个按照优先级排序的队列。
网友评论