最近想学习JUC的内容,就先攻克一下队列吧,平时自己用queue的场景较少,倒是了解过有很多东西是基于queue的,比如消息中间件啊。还是从常用的一些方法入手。
1.构造函数:ArrayBlockingQueue (int capacity)
public ArrayBlockingQueue(int capacity) { this(capacity, false); } public ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); //初始化数组的长度 this.items = new Object[capacity]; //可重入锁,设置为非公平锁 lock = new ReentrantLock(fair); notEmpty = lock.newCondition();//非空condition notFull = lock.newCondition();//非满condition }
2.add(E e)增加一个元索 。如果队列已满,则抛出一个IIIegaISlabEepeplian异常
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
//添加一个元素并返回true 如果队列已满,则返回false
public boolean offer(E e) {
checkNotNull(e);//检查e是否为null
//保证线程安全,同步
final ReentrantLock lock = this.lock;
lock.lock();
try {
//判断数组容量是否已满
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
private void enqueue(E x) {
final Object[] items = this.items;
items[putIndex] = x;
//如果数组容量满了,那么 putIndex(下一次放入的位置)设置为0
//记录下次放进去的位置,是从头到尾:有点类似与指针一样
if (++putIndex == items.length)
putIndex = 0;
count++;
notEmpty.signal();//非空 线程唤醒
}
3.remove() 移除并返回队列头部的元素。如果队列为空,则抛出一个NoSuchElementException异常
public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
//移除并返问队列头部的元素 如果队列为空,则返回null
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
}
private E dequeue() {
final Object[] items = this.items;
@SuppressWarnings("unchecked")
E x = (E) items[takeIndex];
items[takeIndex] = null;
//记录下次拿出来的位置
if (++takeIndex == items.length)
takeIndex = 0;
count--;
if (itrs != null)
itrs.elementDequeued();
notFull.signal();//非满 线程唤醒
return x;
}
4.peek() 返回队列头部的元素。如果队列为空,则返回null
public E peek() { final ReentrantLock lock = this.lock; lock.lock(); try { //takeIndex是 下一个应该被拿出来的下标 return itemAt(takeIndex); // null when queue is empty } finally { lock.unlock(); } } final E itemAt(int i) { return (E) items[i]; }5.put(E e) 添加一个元素。如果队列满,则阻塞
public void put(E e) throws InterruptedException { //检查e是否为null checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly();//可中断地获取锁 try { while (count == items.length) notFull.await();//当前线程等待 enqueue(e); } finally { lock.unlock(); } }
6.take() 移除并返回队列头部的元素 ,如果队列为空,会阻塞
public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly();//可中断地获取锁 try { while (count == 0) notEmpty.await();//当前线程挂起 return dequeue(); } finally { lock.unlock(); } }