阻塞队列源码解析

2017-07-16  本文已影响0人  a乐乐_1234

阻塞队列接口

BlockingQueue<E>的方法

既然是队列,说明遵循先进先出的规则(FIFO),肯定有入队和出队的方法,看了一下注释,有几种不同的出队入队方法,下面列举了一下:

| | 抛异常 | 返回值(null/true/false) | 阻塞 | 指定超时时间 |
|:------:|:-------- :|:---------:|:--------:|:-----------------------:|
| 插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
| 删除 | remove() | poll() | take() | poll(time,unit) |
| 检查 | element() | peek() | | |

BlockingQueue的常见实现类
//fair表示是否需要公平性,默认关闭,建议使用默认值
 public ArrayBlockingQueue(int capacity, boolean fair) {
      if (capacity <= 0)
           throw new IllegalArgumentException();
       // 初始化一个数组
       this.items = new Object[capacity];
       //创建ReentrantLock实例
       lock = new ReentrantLock(fair);
       //创建一个非空的条件对象
       notEmpty = lock.newCondition();
       //创建一个非满的条件对象
       notFull =  lock.newCondition();
   }
//入列
 private void enqueue(E x) {
      final Object[] items = this.items;
      items[putIndex] = x;//putIndex表示当前入队的元素索引
      if (++putIndex == items.length)
        putIndex = 0;
     count++;
     notEmpty.signal();//通知因notEmpty条件不满足阻塞的线程解除阻塞
  }
  //出列
  private E dequeue() {
      final Object[] items = this.items;
      @SuppressWarnings("unchecked")
      E x = (E) items[takeIndex];//takeIndex表示当前出列索引
      items[takeIndex] = null;
      if (++takeIndex == items.length)
          takeIndex = 0;
      count--;
      if (itrs != null)
          itrs.elementDequeued();
      notFull.signal();//通知因notFull条件不满足阻塞的线程解除阻塞
      return x;
    }
  //添加元素
  public void put(E e) throws InterruptedException {
     checkNotNull(e);//检查元素非空
     final ReentrantLock lock = this.lock;
     lock.lockInterruptibly();//获取锁
     try {
         while (count == items.length)  //队列满了
             notFull.await();//当前线程进入条件等待集,直到其他线程调用notFull.signal方法解除阻塞
         enqueue(e);  //入列
     } finally {
         lock.unlock();  //解锁
     }
 }
//删除元素
public E take() throws InterruptedException {
     final ReentrantLock lock = this.lock;
     lock.lockInterruptibly();
     try {
         while (count == 0)  //队列为空
            notEmpty.await();  //当前线程进入条件等待集,直到其他线程调用notEmpty.signal方法解除阻塞
         return dequeue();  //出列
     } finally {
         lock.unlock();
    }
 }
上一篇 下一篇

猜你喜欢

热点阅读