天天看點

阻塞算法和非阻塞算法對比

非阻塞算法用硬體的原生形态代替JVM的鎖定代碼路徑,進而在更細的粒度層次上(獨立的記憶體位置)進行同步,失敗的線程也可以立即重試,而不會被挂起後重新排程。更細的粒度降低了争用的機會,不用重新排程就能重試的能力也降低了争用的成本。即使有少量失敗的 CAS 操作,這種方法仍然會比由于鎖争用造成的重新排程快得多。

有些非阻塞算法步驟的執行是要冒險的,因為知道如果CAS不成功可能不得不重做。非阻塞算法通常叫作樂觀算法,因為它們繼續操作的假設是不會有幹擾。如果發現幹擾,就會回退并重試。

在輕度到中度的争用情況下,非阻塞算法的性能會超越阻塞算法,因為CAS的多數時間都在第一次嘗試時就成功,而發生争用時的開銷也不涉及線程挂起和上下文切換,隻多了幾個循環疊代。沒有争用的CAS要比沒有争用的鎖便宜得多(這句話肯定是真的,因為沒有争用的鎖涉及CAS加上額外的處理),而争用的CAS 比争用的鎖擷取涉及更短的延遲。在高度争用的情況下(即有多個線程不斷争用一個記憶體位置的時候),基于鎖的算法開始提供比非阻塞算法更好的吞吐率,因為當線程阻塞時,它就會停止争用,耐心地等候輪到自己,進而避免了進一步争用。但是,這麼高的争用程度并不常見,因為多數時候,線程會把線程本地的計算與争用共享資料的操作分開,進而給其他線程使用共享資料的機會。(這麼高的争用程度也表明需要重新檢查算法,朝着更少共享資料的方向努力。)

本文轉自 古道卿 51CTO部落格,原文連結:http://blog.51cto.com/gudaoqing/1426022