1、队列Queue介绍
Queue是JDK1.5引入的接口,继承Collection接口,是Collection框架的新成员,是种先进先出(FIFO)的队列。
public interface Queue<E> extends Collection<E>{
boolean add(E e);
boolean offer(E e);
E remove();
E poll();
E element();
E peek();
}
除了基本的Collection
操作外,队列还提供其他的插入、提取和检查操作。每个方法都存在两种形式:一种抛出异常(操作失败时),另一种返回一个特殊值(null 或 false,具体取决于操作)。
抛出异常 | 返回特殊值 | |
插入 | add(e) | offer(e) |
移除 | remove() | poll() |
检查 | element() | peek() |
boolean | add(E e) 将指定的元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException。 |
E | element() 获取,但是不移除此队列的头。 |
boolean | offer(E e) 将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,此方法通常要优于 add(E) ,后者可能无法插入元素,而只是抛出一个异常。 |
E | peek() 获取但不移除此队列的头;如果此队列为空,则返回 null。 |
E | poll() 获取并移除此队列的头,如果此队列为空,则返回 null。 |
E | remove() 获取并移除此队列的头。 |
remove()
或
poll()
所移除的元素。
offer
方法可插入一个元素,否则返回 false。这与 Collection.add
方法不同,该方法只能通过抛出未经检查的异常使添加元素失败。offer 方法设计用于正常的失败情况,而不是出现异常的情况,例如在容量固定(有界)的队列中。
remove()
和 poll()
方法可移除和返回队列的头。到底从队列中移除哪个元素是队列排序策略的功能,而该策略在各种实现中是不同的。remove() 和 poll() 方法仅在队列为空时其行为有所不同:remove() 方法抛出一个异常,而 poll() 方法则返回 null。
element()
和 peek()
返回,但不移除,队列的头。
Queue 实现通常不允许插入 null 元素,尽管某些实现(如 LinkedList
)并不禁止插入 null。即使在允许 null 的实现中,也不应该将 null 插入到 Queue 中,因为 null 也用作 poll 方法的一个特殊返回值,表明队列不包含元素。
BlockingQueue
接口定义了那些等待元素出现或等待队列中有可用空间的方法,这些方法扩展了此接口。
BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:
抛出异常 | 特殊值 | 阻塞 | 超时 | |
插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
移除 | remove() | poll() | take() | poll(time, unit) |
检查 | element() | peek() | 不可用 | 不可用 |
void | put(E e) 将指定元素插入此队列中,将等待可用的空间(如果有必要)。 |
E | take() 获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要) |
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
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();
}
}