介绍
有界阻塞队列,该队列遵循FIFO。存入队尾,取出队首。
使用
使用较简单就不介绍了。
源码解析
- ReentrantLock+Condition原理
一个ReentrantLock两个Condition,存取共用一个锁,一个Condition控制存,一个Condition控制取
//存取共用锁
final ReentrantLock lock;
//存唤醒,取等待
private final Condition notEmpty;
//存等待,取唤醒
private final Condition notFull;
- offer(E e) (add(E e)和offer一样)
如果容量已满,则返回false,添加失败
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
- put(E e)
如果容量已满,则等待,等待容量释放了一些时,再唤醒,执行加入队列
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);
} finally {
lock.unlock();
}
}
- offer(E e, long timeout, TimeUnit unit)
在timeout时间内,如果容量一直处于满的状态,则添加失败,返回false;
timeout<=0,则返回false
public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
checkNotNull(e);
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length) {
if (nanos <= 0)
return false;
nanos = notFull.awaitNanos(nanos);
}
enqueue(e);
return true;
} finally {
lock.unlock();
}
}
- poll()
取队尾数据,唤醒等待
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
}
- take()
取元素,如果容量为空,则等待数据加入再取
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
- poll(long timeout, TimeUnit unit)
在指定时间内,如果容量一直为空,则返回null;
timeout<=0,则返回null
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0) {
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
return dequeue();
} finally {
lock.unlock();
}
}