我的線程永遠運行並在ConcurrentLinkedQueue#peek()之後調用ConcurrentLinkedQueue#poll()。將ConcurrentLinkedQueue#poll()封鎖嗎?
但在某些情況下,線程似乎掛起。我知道這是有點含糊 ,但人們可以確認方法poll()或peek()將從塊塊。謝謝。
我的線程永遠運行並在ConcurrentLinkedQueue#peek()之後調用ConcurrentLinkedQueue#poll()。將ConcurrentLinkedQueue#poll()封鎖嗎?
但在某些情況下,線程似乎掛起。我知道這是有點含糊 ,但人們可以確認方法poll()或peek()將從塊塊。謝謝。
對於我所知道的,ConcurrentLinkedQueue是一個「等待」的實現。
所以我必須假設每個獨立的電話poll()
或peek()
將從不阻止。
該集合上的原子操作是同步的,每個單獨的隊列調用都是線程安全的。
代碼必須存在問題。舉例來說,如果你這樣做:
Object obj;
if (queue.peek() != null)
obj = queue.poll()
不garentee這obj
不會null
。
根據Javadoc,似乎peek()和poll()不應該被阻塞。我匆匆做了一個快速的生產者/消費者測試,並且我沒有阻止。
我不相信你的問題是由於這一點,但民意調查()和PEEK()可以(至少在理論上)塊:
顧名思義,的ConcurrentLinkedQueue實現爲鏈表。當輪詢或窺視時,實現嘗試從頭開始並遍歷鏈接節點,試圖找到未被刪除的節點。如果找到非空節點,則返回該節點,如果到達結尾,則返回該隊列爲空,但如果它找到已刪除節點,則重試。
所以考慮這個序列。 P是一個生產者線程,我們有兩個消費者線程C1和C2:
P: queue.add()
C1: starts queue.poll(), begins to inspect first node
C2: completes a queue.poll() removing the item.
P: queue.add()
C1: continues inspecting the first node, notes that it is deleted.
Restarts and begins to inspect the new first node.
C2: completes a queue.poll() removing the item.
P: queue.add()
C1: continues inspecting the first node, notes that it is deleted.
Restarts and begins to inspect the new first node.
etc.
所以輪詢()和PEEK()將阻塞,直到他們能夠確定隊列是否爲空。
但是,除非你使用一些非常奇怪的線程優先級,這種情況是不太可能的,高度,我建議你在別處尋找你的bug。
請發佈您的代碼/單元測試,以便我們可以運行並驗證代碼的某些方面不會導致問題 – basszero 2009-02-19 11:53:43