BlockingQueue接口分析

83 阅读2分钟

简介

一个阻塞队列接口定义,当队列为空时,取数据等待;当队列满时,存数据等待。
BlockingQueue定义的常用方法如下:

\抛出异常特定值阻塞超时
Insertadd(e)offer(e)put(e)offer(e, time, unit)
Removeremove()poll()take()poll(time,unit)
Examieelement()peek()--

1)add(e):把e加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则抛出异常

2)offer(e):表示如果可能的话,将e加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.

3)put(e):把e加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.

4)poll(time,unit):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null

5)take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止

其中:BlockingQueue 不接受null 元素。试图add、put 或offer 一个null 元素时,某些实现会抛出NullPointerException。null 被用作指示poll 操作失败的警戒值。

阻塞队列不接受null值元素,尝试存入null值元素会抛异常。null值用来表示poll()操作失败。
阻塞队列常用场景:生产者消费者

 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();
     }
   }

某个线程向BlockingQueue中插入一个对象的操作happen-before随后的其他线程获取或删除操作这个对象的操作