LinkedBlockingQueue原始碼講解
阿新 • • 發佈:2018-12-12
尊重原創,轉載請標明出處 http://blog.csdn.net/abcdef314159
原始碼:\sources\Android-25
說到LinkedBlockingQueue,不得不提到LinkedBlockingDeque,他倆差不多,只不過LinkedBlockingDeque是雙向的佇列,而LinkedBlockingQueue是單向的佇列,我們看一下他的節點就知道了
Node只有後一個沒有前一個,並且他是有容量限制的,容量大小是capacity,容量滿了如果再加入就會阻塞。來看第一個方法dequeue/** * Linked list node class. */ static class Node<E> { E item; /** * One of: * - the real successor Node * - this Node, meaning the successor is head.next * - null, meaning there is no successor (this is the last node) */ Node<E> next; Node(E x) { item = x; } }
再來看其中的一個構造方法LinkedBlockingQueue(Collection<? extends E> c),/** * Removes a node from head of queue. * * @return the node */ //移除一個元素 private E dequeue() { // assert takeLock.isHeldByCurrentThread(); // assert head.item == null; Node<E> h = head; Node<E> first = h.next; //讓自己的下一個指向自己,相當於與連結串列斷開了。 h.next = h; // help GC //然後讓head的先一個成為head元素。 head = first; //head元素的item是空的。 E x = first.item; first.item = null; return x; }
put(E e)方法呼叫的也是enqueue方法,如果滿了就會等待。/** * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}, initially containing the elements of the * given collection, * added in traversal order of the collection's iterator. * * @param c the collection of elements to initially contain * @throws NullPointerException if the specified collection or any * of its elements are 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(); } }
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
然後再看下一個方法peek,表示的是返回head節點的下一個節點值,因為head節點是沒有值的,
public E peek() {
if (count.get() == 0)
return null;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
return (count.get() > 0) ? head.next.item : null;
} finally {
takeLock.unlock();
}
}
接著看unlink(Node<E> p, Node<E> trail)方法,表示斷開p到trail之間的節點,
/**
* Unlinks interior Node p with predecessor trail.
*/
void unlink(Node<E> p, Node<E> trail) {
// assert isFullyLocked();
// p.next is not changed, to allow iterators that are
// traversing p to maintain their weak-consistency guarantee.
p.item = null;
trail.next = p.next;
if (last == p)
last = trail;
if (count.getAndDecrement() == capacity)
notFull.signal();
}
剩下的基本上也沒什麼可說的。