Java中鎖的概念
自旋鎖:為了不放棄CPU執行時間,循環的使用CAS技術對數據進行嘗試更新,直至成功。
悲觀鎖:假定會發生並發沖突,同步所有共享數據的相關操作,從讀書據就開始上鎖。
樂觀鎖:假定沒有沖突,在修改數據時如果發現數據和之前獲取的不一致,則讀取最新數據,然后重試修改。
獨享鎖(寫):給資源加上寫鎖,線程可以修改資源,其它線程不能再加鎖;(單寫)
共享鎖(讀):給資源加上讀鎖后只能讀不能改,其他線程也只能加讀鎖,不能加寫鎖;(多讀)
可重入鎖、不可重入鎖:線程拿到一把鎖之后,可以自由進入同一把鎖同步的其他代碼,則為可重入鎖;否則是不可重入鎖。
公平鎖、非公平鎖:爭搶鎖的順序,如果是按先來后到,則為公平鎖;否則是非公平鎖。
Java中幾種重要的鎖的實現方式:synchronized、ReentrantLock、ReentrantReadWriteLock
同步關鍵字synchronized
屬於最基本的線程通信機制,基於對象監視器實現的。
Java中的每個對象都與一個監視器相關聯,一個線程可以鎖定或解鎖監視器。
一次只有一個線程可以鎖定監視器。
試圖鎖定該監視器的其他線程都會被阻塞,直到他們可以獲得該監視器上的鎖定為止。
特性:可重入、獨享鎖、悲觀鎖
鎖的范圍:類鎖、對象鎖
JVM優化:鎖消除、鎖粗化
提示:同步關鍵字,不僅是實現同步,根據JVM規范還能保證可見性(讀取最新內存數據,結束后寫入主內存)
同步關鍵字加鎖原理:
Java對象頭:
如果對象是數組類型,則虛擬機用3個Word(字寬)存儲對象頭,如果對象是非數組類型,則用2字寬存儲對象頭。在32位虛擬機中,一字寬等於四字節,即32bit。

運行期Mark World 根據鎖的不同狀態而可能的存儲結構如下圖:
對象mark word里面 包含四種狀態tag( 00 01 10 11 )
01 無鎖 00 輕量鎖 10 重量鎖 11 GC廢棄

同步關鍵字,優化內容(JDK1.6之后,即鎖的升級過程):
1.偏向鎖,JVM默認開啟,可以使用參數關閉(減少在無競爭情況,JVM資源消耗)
2.出現兩個及以上的線程爭搶,則升級——>輕量級鎖(CAS修改狀態)
3.線程CAS自旋一定次數之后,升級為重量級鎖(對象的mark word 內部會保存一個監視器鎖的一個地址)
鎖升級過程示意圖如下:
偏向鎖示意圖:

輕量級鎖示意圖:

重量級鎖示意圖:

Monitor構造如下圖所示:

