我們知道鎖的基本原理是,基於將多線程並行任務通過某壹種機制實現線程的串 行執行,從而達到線程安全性的目的。而Lock是juc中實現的鎖接口,他定義了鎖的壹些行為規範,他的設計目的是為了解決 synchronized 關鍵字在壹些並發場景下不適用的問題。
juc 包下的接口,定義了鎖的規範。有多種實現類。
ReentrantLock 重入鎖 壹個持有鎖的線程,在釋放鎖之前。此線程如果再次訪問了該同步鎖的其他的方法,這個線程不需要再次競爭鎖,只需要記錄重入次數。 重入鎖的設計目的是為了解決死鎖的問題
inr() 方法獲取鎖成功並沒有釋放鎖的情況下調用dec()再次獲取鎖,假如沒有重入鎖的話這裏會導致死鎖。此線程如果再次訪問了該同步鎖的其他的方法,這個線程不需要再次競爭鎖,只需要記錄重入次數。
<span style='color:red'>內部是如何實現的?假如線程中斷鎖沒有及時釋放怎麽辦呢</span>
NonfairSync 重入鎖的核心實現
AQS中維護了壹個存儲了等待線程的Node節點的雙端鏈表,有首節點head與尾節點tail,創建壹個Node節點裏面存儲的是當前線程,如果已經有了tail節點則嘗試cas操作添加當前節點到鏈表的尾結點,如果沒有則進行初始化操作cas操作創建壹個head節點並且自旋(沒有任何結束條件的循環)cas操作添加尾結點到鏈表的尾部,最終返回新增的Node節點。
對於插入到等待隊列中的Node節點通過 addWaiter 方法把線程添加到鏈表後,會接著把 Node 作為參數傳遞給 acquireQueued 方法,去再次競爭鎖
掛起當前線程。這裏調用了LockSupport.park(this)把線程掛起了並返回 Thread.interrupted() 線程復位。
釋放鎖的業務邏輯不需要考慮多線程的問題,他還是被壹個線程持有。因為重入鎖的機制state>=1 釋放就是 getState() - releases並跟新state為最新值,如果state=0則返回。