Java.util.concurrent包学习(一) BlockingQueue接口

时间:2023-03-09 01:50:50
Java.util.concurrent包学习(一) BlockingQueue接口

JDK1.7

BlockingQueue<E>接口 (extends Queue<E>)

所有父接口:Collection<E>,Iterable<E>,Queue<E>

所有子接口:BlockingDeque<E>,TransferQueue<E>

所有实现该接口的类:ArrayBlockingQueue,DelayQueue,LinkedBlockingQueue,LinkedTransferQueue,PriorityBlockingQueue,SynchronousQueue,LinkedBlockingDeque

  一种支持操作等待的队列,取元素时如果队列为空则等待队列变为非空,放元素时如果队列满则等待队列有可用空间。元素出入方式为FIFO。

  BlockingQueue的方法有四种形式构成:见下表:

 
  Throws exception Special value Blocks Times out
Insert add(e) offer(e) put(e) offer(e,time,unit)
Remove remove() poll() take() poll(time,unit)
Examine element() peek() not applicable not applicable

  BlockingQueue不接受null值元素,通过add,offer,put方法试图添加null值会抛NullPointerException. 因为null值是用来指明poll方法失败的。

  BlockingQueue有容量界限,任何时候都可以通过remainingCapacity值查看可用容量,当已用容量超过remainingCapacity值时,额外的元素不能无阻塞的添加到队列中。

没有内在容量限制的队列,remainingCapacity会返回Integer.MAX值。

  BlockingQueue实现类设计初衷主要用于生产者-消费者队列,但是也支持了Collection接口,因此,可以使用remove(e)方法从队列中移除任何元素。但是需要注意的是,

这种操作并不高效,偶尔才使用到。

  BlockingQueue实现类都是线程安全(Thread-safe)的,所有排队方法都通过内部锁或者其他并发控制实现了原子操作。但是,像集合堆的操作,addAll(),containsAll(),

retainAll(),removeAll(),实现类中没有特殊规定的话就没有必要实现原子操作,所以,当使用addAll(c)可能会存在添加一部分之后操作失败了。

  代码示例,基于典型的生产者-消费者场景。BlockingQueue可以安全的被用于多个生产者和多核

 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) { ...}
}
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) { ... }
}
void consume(Object x) { ... }
} public class Main{
public static void main(String[] args) {
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();
}
}

  

  

相关文章