時active.poll()
訪問舊元素[]回收在ArrayDequeue.doubleCapacity()
爲其雙端隊列已滿,同時你可以考慮的情況下。
一個可能的時間表:
- 輪詢線程檢查出
active.isEmpty()
返回false
- 輪詢線程調用```活躍。pollFirst()來訪問的元素[]這是不原子
- 一個或多個其它線程在突發調用
active.addLast()
使得active
充滿和doubleCapacity()被觸發
- 在doubleCapacity(),元素[]被替換使用新分配的數組,使舊回收的元素[]回收到GC
- 輪詢線程現在引用回收的元素[],並且可能會得到空值。
我的猜測是,當隊列不爲空時,你想避免同步輪詢。爲了避免由doubleCapacity()引起的競爭,請確保隊列分配的容量足夠大,並且在調用addLast()時不會滿足任何要求。但是,根據實際的實施情況,您可能還需要考慮其他比賽。
來自openJDK的以下源碼僅供參考。
public E pollFirst() {
int h = head;
@SuppressWarnings("unchecked")
E result = (E) elements[h];
// Element is null if deque empty
if (result == null)
return null;
elements[h] = null; // Must null out slot
head = (h + 1) & (elements.length - 1);
return result;
}
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ((tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}
private void doubleCapacity() {
assert head == tail;
int p = head;
int n = elements.length;
int r = n - p; // number of elements to the right of p
int newCapacity = n << 1;
if (newCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
Object[] a = new Object[newCapacity];
System.arraycopy(elements, p, a, 0, r);
System.arraycopy(elements, 0, a, r, p);
elements = a;
head = 0;
tail = n;
}
我認爲OP已經知道,他只是想知道爲什麼簡單檢查'head == tail'可能會失敗。這裏所需的解釋比文檔中的引用要多。 – 2012-04-12 15:26:06