//阻塞式链表队列
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -6903933977591709194L;
//容量
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();
//链表结点
static class Node<E> {
E item;
Node<E> next;
Node(E x) { item = x; }
}
private void signalNotEmpty() {
final ReentrantLock takeLock = this.takeLock;
//获取取元素锁,此处尝试获取锁是因为有可能其他线程已经获取了此锁
//则不唤醒在notEmpty条件队列上等待的线程,直到取元素锁可用
takeLock.lock();
try {
notEmpty.signal();
} finally {
takeLock.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条件队列上等待
notFull.await();//在notFull条件队列上等待
}
enqueue(node);//入队
c = count.getAndIncrement();// 更新元素个数并返回前值
if (c + 1 < capacity)// 元素个数小于容量
notFull.signal();// 唤醒在notFull条件上等待的某个线程
} finally {
putLock.unlock();
}
if (c == 0)//添加元素之前链表元素个数为0,现在添加了元素,唤醒在notEmpty条件上等待的线程
signalNotEmpty();
}
//取元素,如果链表元素为0,则等待
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
// 如果当前线程未被中断,则获取元素锁
takeLock.lockInterruptibly();
try {
while (count.get() == 0) {// 当前链表元素个数为0
notEmpty.await();//在notEmpty条件上等待
}
x = dequeue();//出队列
c = count.getAndDecrement();//当前链表元素减1,并返回旧值
if (c > 1)//链表元素个数大于1,唤醒在notEmpty上等待的某个线程
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)//结点出队列之前的元素个数为指定容量
signalNotFull();//唤醒在notFull条件上等待的线程
return x;
}
//删除指定元素
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();
}
}
void unlink(Node<E> p, Node<E> trail) {
p.item = null;
trail.next = p.next;
if (last == p)
last = trail;
//删除指定元素队列之前的元素个数为指定容量
if (count.getAndDecrement() == capacity)
notFull.signal();
}
}
LinkedBlockingQueue源码阅读
最新推荐文章于 2022-07-26 18:16:21 发布