多線程鎖的升級原理是什麼?

鎖的級別:面試

無鎖->偏向鎖->輕量級鎖->重量級鎖多線程

鎖分級別緣由:性能

沒有優化前,sychroniezed是重量級鎖(悲觀鎖),使用wait、notify、notifyAll來切換線程狀態很是消耗系統資源,線程的掛起和喚醒間隔很短暫,這樣很浪費資源,影響性能。因此JVM對sychronized關鍵字進行了優化,把鎖分爲無鎖、偏向鎖、輕量級鎖、重量級鎖。優化

1、無鎖spa

沒有對資源進行鎖定,全部的線程都能訪問並修改同一個資源,但同時只有一個線程能修改爲功,其它修改失敗的線程會不斷重試直到修改爲功。操作系統

2、偏向鎖.net

對象的代碼一直被同一線程執行,不存在多個線程競爭,該線程在後續執行中自動獲取鎖,下降獲取鎖帶來的性能開銷。偏向鎖,指的是偏向第一個加鎖線程,該線程是不會主動釋放偏向鎖的,只有當其餘線程嘗試競爭偏向鎖纔會被釋放。線程

偏向鎖的撤銷,須要在某個時間點上沒有字節碼正在執行時,先暫停偏向鎖的線程,而後判斷鎖對象是否處於被鎖定狀態,若是線程不處於活動狀態,則將對象頭設置成無鎖狀態,並撤銷偏向鎖。對象

若是線程處於活動狀態,升級爲輕量級鎖的狀態。blog

3、輕量級鎖

輕量級鎖是指當鎖是偏向鎖的時候,被第二個線程B訪問,此時偏向鎖就會升級爲輕量級鎖,線程B會經過自旋的形式嘗試獲取鎖,線程不會阻塞,從er提高性能。

當前只有一個等待線程,則該線程將經過自旋進行等待。可是當自旋超過必定次數時,輕量級鎖邊會升級爲重量級鎖,當一個線程已持有鎖,另外一個線程在自旋,而此時第三個線程來訪時,輕量級鎖也會升級爲重量級鎖。

注:自旋是什麼?

自旋(spinlock)是指當一個線程獲取鎖的時候,若是鎖已經被其它線程獲取,那麼該線程將循環等待,而後不斷的判斷鎖是否可以被成功獲取,直到獲取到鎖纔會退出循環。

4、重量級鎖

指當有一個線程獲取鎖以後,其他全部等待獲取該鎖的線程都會處於阻塞狀態。

重量級鎖經過對象內部的監聽器(monitor)實現,而其中monitor的本質是依賴於底層操做系統的Mutex Lock實現,操做系統實現線程之間的切換須要從用戶態切換到內核態,切換成本很是高。

5、鎖狀態對比:

  偏向鎖 輕量級鎖 重量級鎖
使用場景 只有一個線程進入同步塊 雖然不少線程,但沒有衝突,線程進入時間錯開於是並未爭搶鎖 發生了鎖爭搶的狀況,多條線程進入同步塊爭用鎖
本質 取消同步操做 CAS操做代替互斥同步 互斥同步
優勢 不阻塞,執行效率高(只有第一次獲取偏向鎖時須要CAS操做,後面只是比對ThreadId) 不會阻塞 不會空耗CPU
缺點

適用場景太侷限。若競爭產生,會有額外的偏向鎖撤銷的消耗

長時間獲取不到鎖空耗CPU 阻塞,上下文切換,重量級操做,消耗操做系統資源

6、CAS是什麼呢?

CAS即即比較和替換,當使用CAS替換新值不成功時,自旋,從新得到原值和新值再試一次直到成功爲止。

CAS經過無鎖操做提升了系統的吞吐率,高效的解決了原子操做問題。

淺談Java多線程CAS原理

 

天天一道面試題,持續更新@目錄

相關文章
相關標籤/搜索