2015-11-19 86 views
3

BlockingQueue中的同步由Lock實現,而ConcurrentLinkedQueue使用涉及CAS的無鎖算法。但我的問題是關於上下文切換開銷。如果有10個線程將來自BlockingQueue的請求排隊,那麼每次只有一個會鎖定隊列,並且將放置9個上下文切換(9個線程將鬆動),而在ConcurrentLinkedQueue的情況下,沒有上下文切換開銷,但是儘可能時間切片關注所有10個線程會在時間片結束後一次又一次地進行上下文切換,並且與BlockingQueue相比,這不會導致更多的上下文切換開銷?哪一個導致更少的上下文切換開銷?BlockingQueue中的上下文切換開銷

+0

如果兩個線程調用,則可能不會有任何上下文切換。首先是因爲,除非線程除了儘可能快地輪詢隊列並拋出節點之外什麼都不做,它們可能會在互斥體中花費相對較少的時間,並且不會有太多的爭用。其次,因爲即使它們偶爾會發生碰撞,您的JVM可能也會使用複雜的混合鎖定算法,這種算法不會阻止線程的丟失,直到獲勝者花費的時間超過一小段時間來保持互斥鎖爲止。 –

+0

但是你是對的,如果兩個或多個線程儘可能快地調用'concurrentLinkedQueue.poll()',那麼它將永遠不會阻止它們中的任何一個。 –

+1

我的意見是,如果你遇到一個情況,你有10個線程同時等待資源的訪問,那麼你的問題不是如何處理這個爭用,而是你爲什麼有這麼多的線程擺在首位。 CAS不是萬能的,它是一種優化,只要你沒有溢出,它就一直存在。 – didierc

回答

0

ConcurrentLinkedQueue沒有take(),所以我們不能比較。 所以你比較.poll()。 我們可以辯論爲什麼你不使用BQ.take()和BQ.put()執行signal()而不是signalAll()並且只喚醒一個線程而不是10的事實,但這是另一個問題。

BQ鎖使用可重入鎖來實現,它們本身使用CAS。

唯一的區別在於這種鎖定的「公平性」(參見再入行鎖的屬性),並且可能是併發鏈接隊列的更緊密的鎖編碼(更小的堆棧幀深度)。

微基準測試是,檢查OS`arrayBlockingQueue.poll()`的CTX開關次數,以及JVM探查熱點...