鎖的級別:面試
無鎖->偏向鎖->輕量級鎖->重量級鎖多線程
鎖分級別緣由:性能
沒有優化前,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經過無鎖操做提升了系統的吞吐率,高效的解決了原子操做問題。