ArrayBlockingQueue(阻塞队列的一种) 的本质是一个有界数组,队列中元素遵循先进先出的规则。 这种队列是一种典型的有界缓冲区,一旦建立,他的长度就不能再改变。数组
final Object[] items;// 队列容器 int count;// 队列中的元素真实个数 final ReentrantLock lock;// 主锁,控制全部的访问 int takeIndex; /** 下一个要取出的元素索引*/ int putIndex;/** 下一个要存放的索引*/ private final Condition notEmpty; /** 标记队列是不是空*/ private final Condition notFull; /** 至关于一个标志位, 标记队列是否存满*/
添加元素的方法this
// 添加元素 public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly();// 调用后会一直等待获取锁,可是会响应中断,//这个方法优先考虑响应中断,而不是响应锁的普通获取或重入获取。 try { while (count == items.length)// 当队列存满时 notFull.await();// 阻塞等待 enqueue(e);// 存入队列 并 唤醒 notEmpty 锁 } finally { lock.unlock(); } } // 非空校验 private static void checkNotNull(Object v) { if (v == null) throw new NullPointerException(); } // 入队 private void enqueue(E x) { final Object[] items = this.items; items[putIndex] = x; if (++putIndex == items.length)// 若是队列满了 putIndex = 0;// 从头开始放 count++; notEmpty.signal();//唤醒 }
取出元素的方法code
// 取出元素 public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await();// 队列中元素个数为0,等待 return dequeue();// 返回队列中的元素 } finally { lock.unlock(); } } // 出队 private E dequeue() { final Object[] items = this.items;// 指向容器 E x = (E) items[takeIndex];// 待返回的元素 items[takeIndex] = null;// 弹出队列 if (++takeIndex == items.length)// 若是队列元素取出来完了 takeIndex = 0;// 从头开始取元素 count--;// 队列元素个数 减一 if (itrs != null)// 这个能够忽略 itrs.elementDequeued(); notFull.signal();// 释放锁。说明队列没有满, 能够入队, return x; }
本文只是简单介绍了 ArrayBlockingQueue 中最简单 且 最经常使用的方法,它自己其实还有不少实用的方法,好比预防超时之类的,之后会继续分享。索引