2009-02-19 43 views
2

我的線程永遠運行並在ConcurrentLinkedQueue#peek()之後調用ConcurrentLinkedQueue#poll()。將ConcurrentLinkedQueue#poll()封鎖嗎?

但在某些情況下,線程似乎掛起。我知道這是有點含糊 ,但人們可以確認方法poll()或peek()將從塊塊。謝謝。

+0

請發佈您的代碼/單元測試,以便我們可以運行並驗證代碼的某些方面不會導致問題 – basszero 2009-02-19 11:53:43

回答

2

對於我所知道的,ConcurrentLinkedQueue是一個「等待」的實現。

所以我必須假設每個獨立的電話poll()peek()從不阻止

該集合上的原子操作是同步的,每個單獨的隊列調用都是線程安全的。

代碼必須存在問題。舉例來說,如果你這樣做:

Object obj; 

if (queue.peek() != null) 
    obj = queue.poll() 

不garentee這obj不會null

0

根據Javadoc,似乎peek()和poll()不應該被阻塞。我匆匆做了一個快速的生產者/消費者測試,並且我沒有阻止。

0

我不相信你的問題是由於這一點,但民意調查()和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。