一个由链表结构组成的有界阻塞队列
成员变量
// 允许的最大容量
private final int capacity;
// 当前节点个数,因为有两个锁,所以节点个数采用原子类
private final AtomicInteger count = new AtomicInteger();
// 链表的头节点
transient Node<E> head;
// 链表的尾节点
private transient Node<E> last;
// 出队锁
private final ReentrantLock takeLock = new ReentrantLock();
// 出队锁的等待队列
private final Condition notEmpty = takeLock.newCondition();
// 入队锁
private final ReentrantLock putLock = new ReentrantLock();
// 入队锁的等待队列
private final Condition notFull = putLock.newCondition();
构造方法
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
// 头节点不存储元素
last = head = new Node<E>(null);
}
public LinkedBlockingQueue(Collection<? extends E> c) {
this(Integer.MAX_VALUE);
final ReentrantLock putLock = this.putLock;
putLock.lock(); // Never contended, but necessary for visibility
try {
int n = 0;
for (E e : c) {
if (e == null)
throw new NullPointerException();
if (n == capacity)
throw new IllegalStateException("Queue full");
enqueue(new Node<E>(e));
++n;
}
count.set(n);
} finally {
putLock.unlock();
}
}
入队
// 入队,阻塞
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
// 获取入队锁
putLock.lockInterruptibly();
try {
// 如果个数已满,则当前线程进入队锁的等待队列
while (count.get() == capacity) {
notFull.await();
}
// 添加元素后,个数加1
enqueue(node);
c = count.getAndIncrement();
// 如果当前容量还未满,则通知入队锁等待队列的线程
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
// 如果添加元素前的个数为0,则通知出队锁等待队列的线程
if (c == 0)
signalNotEmpty();
}
// 入队,与put相比有个超时等待,超过时间就取消入队
public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
if (e == null) throw new NullPointerException();
long nanos = unit.toNanos(timeout);
int c = -1;
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
if (nanos <= 0)
return false;
nanos = notFull.awaitNanos(nanos);
}
enqueue(new Node<E>(e));
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
return true;
}
// 入队,不会超时等待或者阻塞等待,容量未满时添加元素,容量已满时取消添加
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final AtomicInteger count = this.count;
if (count.get() == capacity)
return false;
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
if (count.get() < capacity) {
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
}
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
return c >= 0;
}
出队
// 出队,阻塞
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
// 获取出队锁
takeLock.lockInterruptibly();
try {
// 如果当前容量为0,则线程进出队锁的等待队列
while (count.get() == 0) {
notEmpty.await();
}
// 先出队,再进行个数操作
x = dequeue();
c = count.getAndDecrement();
// 如果容量超过1,则唤醒notEmpty等待队列的线程
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
// 如果之前个数已满,则唤醒notFull等待队列的线程
if (c == capacity)
signalNotFull();
return x;
}
// 出队,超时等待,超时后取消出队
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
E x = null;
int c = -1;
long nanos = unit.toNanos(timeout);
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (count.get() == 0) {
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
// 出队,非阻塞、非超时等待,如果个数为0,则取消出队
public E poll() {
final AtomicInteger count = this.count;
if (count.get() == 0)
return null;
E x = null;
int c = -1;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
if (count.get() > 0) {
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
}
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
包含
// 包含
public boolean contains(Object o) {
if (o == null) return false;
// 获取入队锁和出队锁
fullyLock();
try {
// 遍历链表,找出是否包含元素
for (Node<E> p = head.next; p != null; p = p.next)
if (o.equals(p.item))
return true;
return false;
} finally {
fullyUnlock();
}
}
删除
// 删除
public boolean remove(Object o) {
if (o == null) return false;
// 获取入队锁和出队锁
fullyLock();
try {
// 遍历链表删除元素
for (Node<E> trail = head, p = trail.next;
p != null;
trail = p, p = p.next) {
if (o.equals(p.item)) {
unlink(p, trail);
return true;
}
}
return false;
} finally {
fullyUnlock();
}
}