zoukankan      html  css  js  c++  java
  • java1.7集合源码阅读:ArrayBlockingQueue

      ArrayBlockingQueue是一个先进先出线程安全的队列,队列头部是进入队列时间最长的元素,队尾是进入队列时间最短的元素,同时队列的最大容量是固定的。

    先看类定义:

    1 public class ArrayBlockingQueue<E> extends AbstractQueue<E>
    2         implements BlockingQueue<E>, java.io.Serializable {
    3       ......
    4 }
    ArrayBlockingQueue实现了BlockingQueue接口,是一个阻塞队列实现,内部通过数组进行数据存储:
    1  /** The queued items */
    2     final Object[] items;
    3 
    4     /** items index for next take, poll, peek or remove */
    5     int takeIndex;
    6 
    7     /** items index for next put, offer, or add */
    8     int putIndex;

    对元素的增加操作,主要提供了三种使用场景:添加(队列已满则返回false)、限时等待添加,无限等待添加;

     1   /**
     2      * Inserts the specified element at the tail of this queue if it is
     3      * possible to do so immediately without exceeding the queue's capacity,
     4      * returning {@code true} upon success and throwing an
     5      * {@code IllegalStateException} if this queue is full.
     6      *
     7      * @param e the element to add
     8      * @return {@code true} (as specified by {@link Collection#add})
     9      * @throws IllegalStateException if this queue is full
    10      * @throws NullPointerException if the specified element is null
    11      */
    12     public boolean add(E e) {    //add 和offer(e) 是一样的
    13         return super.add(e);
    14     }
    15 
    16     /**
    17      * Inserts the specified element at the tail of this queue if it is
    18      * possible to do so immediately without exceeding the queue's capacity,
    19      * returning {@code true} upon success and {@code false} if this queue
    20      * is full.  This method is generally preferable to method {@link #add},
    21      * which can fail to insert an element only by throwing an exception.
    22      *
    23      * @throws NullPointerException if the specified element is null
    24      */
    25     public boolean offer(E e) {
    26         checkNotNull(e);
    27         final ReentrantLock lock = this.lock;
    28         lock.lock();
    29         try {
    30             if (count == items.length)
    31                 return false;
    32             else {
    33                 insert(e);
    34                 return true;
    35             }
    36         } finally {
    37             lock.unlock();
    38         }
    39     }
    40 
    41     /**
    42      * Inserts the specified element at the tail of this queue, waiting
    43      * for space to become available if the queue is full.
    44      *
    45      * @throws InterruptedException {@inheritDoc}
    46      * @throws NullPointerException {@inheritDoc}
    47      */
    48     public void put(E e) throws InterruptedException {
    49         checkNotNull(e);
    50         final ReentrantLock lock = this.lock;
    51         lock.lockInterruptibly();
    52         try {
    53             while (count == items.length)
    54                 notFull.await();
    55             insert(e);
    56         } finally {
    57             lock.unlock();
    58         }
    59     }
    60 
    61     /**
    62      * Inserts the specified element at the tail of this queue, waiting
    63      * up to the specified wait time for space to become available if
    64      * the queue is full.
    65      *
    66      * @throws InterruptedException {@inheritDoc}
    67      * @throws NullPointerException {@inheritDoc}
    68      */
    69     public boolean offer(E e, long timeout, TimeUnit unit)   // 限时等待添加
    70         throws InterruptedException {
    71 
    72         checkNotNull(e);
    73         long nanos = unit.toNanos(timeout);
    74         final ReentrantLock lock = this.lock;
    75         lock.lockInterruptibly();
    76         try {
    77             while (count == items.length) {
    78                 if (nanos <= 0)
    79                     return false;
    80                 nanos = notFull.awaitNanos(nanos);
    81             }
    82             insert(e);
    83             return true;
    84         } finally {
    85             lock.unlock();
    86         }
    87     }

    对元素的获取同样提供了三种使用场景:添加(队列空则返回null)、限时等待获取,无限等待获取;

     1  public E poll() {
     2         final ReentrantLock lock = this.lock;
     3         lock.lock();
     4         try {
     5             return (count == 0) ? null : extract();
     6         } finally {
     7             lock.unlock();
     8         }
     9     }
    10 
    11     public E take() throws InterruptedException {
    12         final ReentrantLock lock = this.lock;
    13         lock.lockInterruptibly();
    14         try {
    15             while (count == 0)
    16                 notEmpty.await();
    17             return extract();
    18         } finally {
    19             lock.unlock();
    20         }
    21     }
    22 
    23     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
    24         long nanos = unit.toNanos(timeout);
    25         final ReentrantLock lock = this.lock;
    26         lock.lockInterruptibly();
    27         try {
    28             while (count == 0) {
    29                 if (nanos <= 0)
    30                     return null;
    31                 nanos = notEmpty.awaitNanos(nanos);
    32             }
    33             return extract();
    34         } finally {
    35             lock.unlock();
    36         }
    37     }

    获取队列元素大小也是强一致性的:

     1   /**
     2      * Returns the number of elements in this queue.
     3      *
     4      * @return the number of elements in this queue
     5      */
     6     public int size() {
     7         final ReentrantLock lock = this.lock;
     8         lock.lock();
     9         try {
    10             return count;
    11         } finally {
    12             lock.unlock();
    13         }
    14     }

    元素的删除也是同步的,元素存在则删除返回true,如果元素不存在则返回false:

     1   /**
     2      * Removes a single instance of the specified element from this queue,
     3      * if it is present.  More formally, removes an element {@code e} such
     4      * that {@code o.equals(e)}, if this queue contains one or more such
     5      * elements.
     6      * Returns {@code true} if this queue contained the specified element
     7      * (or equivalently, if this queue changed as a result of the call).
     8      *
     9      * <p>Removal of interior elements in circular array based queues
    10      * is an intrinsically slow and disruptive operation, so should
    11      * be undertaken only in exceptional circumstances, ideally
    12      * only when the queue is known not to be accessible by other
    13      * threads.
    14      *
    15      * @param o element to be removed from this queue, if present
    16      * @return {@code true} if this queue changed as a result of the call
    17      */
    18     public boolean remove(Object o) {
    19         if (o == null) return false;
    20         final Object[] items = this.items;
    21         final ReentrantLock lock = this.lock;
    22         lock.lock();
    23         try {
    24             for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
    25                 if (o.equals(items[i])) {
    26                     removeAt(i);
    27                     return true;
    28                 }
    29             }
    30             return false;
    31         } finally {
    32             lock.unlock();
    33         }
    34     }

    ArrayBlockingQueue的所有操作都是通过加锁进行同步的,代码也比较简单。



  • 相关阅读:
    Pandas提取数据存入excel
    获取页面元素二
    selenium如何解决IE自动填充表单问题
    IE浏览器相关的问题及解决方案
    TestNG入门教程(TestNG介绍、在Eclipse中安装TESTNG、测试小例子、基本注解、如何执行测试、按顺序执行Case、异常测试、组合测试、参数化测试、忽略测试、依赖测试、测试结果报告)
    selenium Webdriver 处理 —— 通过时间控件给文本框赋值
    列表翻页,选中目标记录
    bug统计
    在eclipse中安装TestNG
    selenium搭建、运行
  • 原文地址:https://www.cnblogs.com/jessezeng/p/5446950.html
Copyright © 2011-2022 走看看