5

我試圖讀取Synchronous Queue的實現
對我來說這並不那麼簡單。它似乎在使用鏈接列表,其中每個節點都與一個線程關聯。
核心部分使用等待任務的旋轉循環放入隊列中。
我想知道爲什麼使用旋轉循環代替wait/notify之類的東西?
現在,這種方式的核心之一是由於這個恆定的自旋循環,對不對?
我想明白了這一點,並得到同步隊列試圖瞭解同步隊列的機制

UPDATE
什麼也困擾着我的設計的粗略認識是服務員線程如何啓動/停止。

+0

這是無鎖算法的基礎 - 注意只有在有東西需要傳輸時才進行旋轉。轉移完成或者如果沒有什麼可做的話,這個方法返回 – assylias

+0

@assylias:在'TransferQueue.transferer'的大部分地方都有一個'continue'而不是'return''。在少數情況下會有返回case我不知道服務員會發生什麼情況,以及他們何時/如何重新啓動 – Jim

回答

4

SynchronousQueue的要點是同步一些通常非常異步的東西 - 一個線程將一個項目放入隊列中,而另一個線程則嘗試從中取出。

SynchronousQueue實際上並不是一個隊列。它沒有容量,沒有內部存儲。它只允許當另一個進程正在嘗試放入隊列時從隊列中取出。

示例:

進程A嘗試放入隊列。現在阻止。 進程B嘗試從隊列中取出。由於有人試圖放置,該項目從A轉移到B,並且兩者都暢通無阻。

過程B嘗試從隊列中取出,但沒有人嘗試放入。所以B現在被封鎖了。過程A現在想要放置一個項目。現在該項目被轉移到B,並且A和B不再被阻止。

關於阻塞:

太陽/ Oracle的JRE實現不使用輪詢,而不是等待/如果你做一個定時操作(如「嘗試走1秒鐘」)通知格局。這是有道理的:它會定期重試,直到時間到了。當你進行非定時操作時(例如「不管需要多長時間」,它都會使用park,如果情況發生變化,它會再次喚醒。在任何情況下,你的內核都不會經常忙於旋轉一個循環。 for (;;)在這種情況下意味着「無限期地重試」,它並不意味着「持續旋轉」

+0

我認爲沒有實際的阻塞。我的意思是阻塞部分是通過一個旋轉循環。這個循環「吃」了cpu的週期。爲什麼不是通過某種形式的'wait'或'sleep'實現的阻塞? – Jim

+0

你認爲錯了,然後;-)有阻塞。這就是爲什麼您鏈接的API文檔打開的句子是「一個阻塞隊列,其中每個插入操作必須等待另一個線程進行相應的刪除操作,反之亦然。」#: –

+1

但你引用了javadoc.I已經提到過我嘗試瞭解在執行'transfer'時發現'for(;;){'的實現。 – Jim