并发编程之BlockingQueue源码解读

public interface BlockingQueue
extends Queue
阻塞队列支持在检索元素时如果队列为空发生阻塞,直到有可以操作的元素。同时在插入元素如果没有多余的容量支持,就阻塞,直到有可用空间

BlockingQueue方法有四种形式,根据处理操作的方式不同,有的能立即得到结果,有的会在某个时间点获得结果:一种方法抛出异常,另一种方法返回特殊值(根据操作的不同,可以为null或false),第三个在操作成功之前无限期阻塞当前线程,第四个在放弃之前仅阻塞给定的最大时间限制。下表总结了这些方法:在这里插入图片描述
不能插入null,如果插入null实现类会报空指针异常
阻塞队列可能有容量限制,否则容量就是Integer.MAX_VALUE

BlockingQueue的实现主要用于生产者-消费者队列,但还支持收集接口。BlockingQueue的实现是线程安全的。所有队列方法都使用内部锁或其他形式的并发控制原子性。
使用示例,基于典型的生产者-消费者场景。注意,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) { ... 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();
   }
 }

阻塞队列满足happens——before即程序中的查询操作发生在从另一个线程中对BlockingQueue访问或删除该元素操作之前。

重要方法

/**
     * 如果可以在不违反容量限制的情况下立即将指定元素插入此队列,
     * 则成功时返回true,如果当前没有可用空间,则抛出IllegalStateException。
     * 当使用容量受限队列时,通常最好使用offer
     * 
     * 
     * @param e 一个要加入的元素
     * @return 添加成功放回true
     * @throws IllegalStateException在没有可用容量的时候 
     * @throws ClassCastException 
     * @throws NullPointerException 
     * @throws IllegalArgumentException if some property of the specified
     *         element prevents it from being added to this queue
     */
    boolean add(E e);

 /**
     *如果可以在不违反容量限制的情况下立即将指定元素插入此队列,
     *则成功时返回true,如果当前没有可用空间,则返回false。
     *当使用容量受限队列时,此方法通常比add(E)更可取,后者只能通过抛出异常才能插入元素。    
     * 

     *@param e the element to add
     * @return {@code true} if the element was added to this queue, else
     *         {@code false}
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null
     * @throws IllegalArgumentException if some property of the specified
     *         element prevents it from being added to this queue
     */
    boolean offer(E e);
/**
     * 将指定的元素插入此队列,必要时等待空间可用。会发生阻塞
     * 
     *
     * @param e the element to add
     * @throws InterruptedException if interrupted while waiting
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null
     * @throws IllegalArgumentException if some property of the specified
     *         element prevents it from being added to this queue
     */
    void put(E e) throws InterruptedException;

/**
     * 将指定的元素插入此队列,如果没有空间空间,则等阻塞指定的时间。
     *
     * @param e the element to add
     * @param timeout how long to wait before giving up, in units of
     *        {@code unit}
     * @param unit a {@code TimeUnit} determining how to interpret the
     *        {@code timeout} parameter
     * @return {@code true} if successful, or {@code false} if
     *         the specified waiting time elapses before space is available
     * @throws InterruptedException 如果在等待时被打断抛出
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null
     * @throws IllegalArgumentException if some property of the specified
     *         element prevents it from being added to this queue
     */
    boolean offer(E e, long timeout, TimeUnit unit)
        throws InterruptedException;

/**
     * 检索并删除此队列的头,如果队列为空就阻塞直到有新的元素加入。
     
     *
     * @return 返回头部元素
     * @throws InterruptedException 如果在等待时被打断抛出
     */
    E take() throws InterruptedException;

 /**
     * 检索并删除此队列的头,如果队列为空,等待指定的时间直到有可操作的元素。
     *
     * @param timeout how long to wait before giving up, in units of
     *        {@code unit}
     * @param unit a {@code TimeUnit} determining how to interpret the
     *        {@code timeout} parameter
     * @返回队列头部, or {@code null} if the
     *         specified waiting time elapses before an element is available
     * @throws InterruptedException 如果在等待时被打断抛出
     */
    E poll(long timeout, TimeUnit unit)
        throws InterruptedException;

    /**
     *返回队列可插入元素的个数,最大为interge的最大值,建议不要用此方法判断插入元素是否成功,因为线程不安全
     *
     * @返回剩余容量
     */
    int remainingCapacity();

    /**
     * 移除一个指定的元素
     *成功返回true,失败返回false
     *
   *Throws:
   *ClassCastException - if the class of the specified element is incompatible with this queue (optional)
   *NullPointerException - if the specified element is null (optional)
     */
    boolean remove(Object o);

    /**
     *判断指定元素是否在队列中
     *
     * @param o object to be checked for containment in this queue
     * @return {@code true} if this queue contains the specified element
     * @throws ClassCastException if the class of the specified element
     *         is incompatible with this queue
     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null
     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
     */
    public boolean contains(Object o);

    /**
     *移除所有元素并将元素添加到集合中
     *
     * @param c the collection to transfer elements into
     * @return the number of elements transferred
     * @throws UnsupportedOperationException if addition of elements
     *         is not supported by the specified collection
     * @throws ClassCastException if the class of an element of this queue
     *         prevents it from being added to the specified collection
     * @throws NullPointerException if the specified collection is null
     * @throws IllegalArgumentException if the specified collection is this
     *         queue, or some property of an element of this queue prevents
     *         it from being added to the specified collection
     */
    int drainTo(Collection<? super E> c);

    /**
     * 移除所有元素并将元素添加到指定大小的集合中
     *
     * @param c the collection to transfer elements into
     * @param maxElements the maximum number of elements to transfer
     * @return the number of elements transferred
     * @throws UnsupportedOperationException if addition of elements
     *         is not supported by the specified collection
     * @throws ClassCastException if the class of an element of this queue
     *         prevents it from being added to the specified collection
     * @throws NullPointerException if the specified collection is null
     * @throws IllegalArgumentException if the specified collection is this
     *         queue, or some property of an element of this queue prevents
     *         it from being added to the specified collection
     */
    int drainTo(Collection<? super E> c, int maxElements);
 ``

发布了23 篇原创文章 · 获赞 2 · 访问量 841

猜你喜欢

转载自blog.csdn.net/qq_34800986/article/details/104631176
今日推荐