在C程序代碼中我們可以利用操作系統提供的互斥鎖來實現同步塊的互斥訪問及線程的阻塞及喚醒等工作。在Java中除了提供Lock API外還在語法層面上提供了synchronized關鍵字來實現互斥同步原語,本文將對synchronized關鍵字詳細分析。?
帶著問題去理解Synchronized
提示
- 請帶著這些問題繼續后文,會很大程度上幫助你更好的理解synchronized。
- Synchronized可以作用在哪里?分別通過對象鎖和類鎖進行舉例。
- Synchronized本質上是通過什么保證線程安全的?分三個方面回答:加鎖和釋放鎖的原理,可重入原理,保證可見性原理。
- Synchronized由什么樣的缺陷?Java Lock是怎么彌補這些缺陷的,
- Synchronized和Lock的對比,和選擇?
- Synchronized在使用時有何注意事項?
- Synchronized修飾的方法在拋出異常時,會釋放鎖嗎?.
- 多個線程等待同一個Synchronized鎖的時候,JM如何選擇下一個獲取鎖的線程?
- Synchronized使得同時只有一個線程可以執行,性能比較差,有什么提升的方法?
- 我想更加靈活的控制鎖的釋放和獲取(現在釋放鎖和獲取鎖的時機都被規定死了),怎么辦?
- 什么是鎖的升級和降級?什么是IM里的偏斜鎖、輕量級鎖、重量級鎖?
- 不同的JDK中對Synchronized有何優化?
Synchronized的使用
在應用Sychronized關鍵字時需要把握如下注意點:
- 把鎖只能同時被一個線程獲取,沒有獲得鎖的線程只能等待;
- 每個實例都對應有自己的一把鎖(this),不同實例之間互不影響;例外:鎖對象是*.class以及synchronized修飾的是static方法的時候,所有對象公用同一把鎖
- synchronized修飾的方法,無論方法正常執行完畢還是拋出異常,都會釋放鎖
對象鎖
包括方法鎖(默認鎖對象為this,當前實例對象)和同步代碼塊鎖(自己指定鎖對象)
代碼塊形式:手動指定鎖定對象,也可是是this,也可以是自定義的鎖
- 示例1?
- ?示例2
?
?
方法鎖形式:synchronized修飾普通方法,鎖對象默認為this?
類鎖
指synchronize修飾靜態的方法或指定鎖對象為Class對象
synchronize修飾靜態方法?
- 示例1
?
- 示例2?
?synchronized指定鎖對象為Class對象
?