可重入鎖又名遞歸鎖,是指在同一個線程在外層方法獲取鎖的時候,再進入該線程的內層方法會自動獲取鎖(前提鎖對象得是同一個對象或者class),不會由於以前已經獲取過還沒釋放而阻塞。Java中ReentrantLock和synchronized都是可重入鎖,可重入鎖的一個優勢是可必定程度避免死鎖。ide
ReentrantLock和synchronized都是重入鎖,測試
可重入鎖的好處:【1.避免死鎖】【2.提高封裝性】ui
電影院預約預約電影院座位spa
預約座位就是個很好的lock鎖場景,預約座位,其實這個背後就是上鎖了線程
首先ReentrantLock和NonReentrantLock都繼承父類AQS,其父類AQS中維護了一個同步狀態status來計數重入次數,status初始值爲0。當線程嘗試獲取鎖時,可重入鎖先嚐試獲取並更新status值,若是status == 0表示沒有其餘線程在執行同步代碼,則把status置爲1,當前線程開始執行。若是status != 0,則判斷當前線程是不是獲取到這個鎖的線程,若是是的話執行status+1,且當前線程能夠再次獲取鎖。而非可重入鎖是直接去獲取並嘗試更新當前status的值,若是status != 0的話會致使其獲取鎖失敗,當前線程阻塞。釋放鎖時,可重入鎖一樣先獲取當前status的值,在當前線程是持有鎖的線程的前提下。若是status-1 == 0,則表示當前線程全部重複獲取鎖的操做都已經執行完畢,而後該線程纔會真正釋放鎖。而非可重入鎖則是在肯定當前線程是持有鎖的線程以後,直接將status置爲0,將鎖釋放。3d
咱們使用 lock.getHoldCount() 打印下獲取鎖的次數 屢次獲取鎖,與釋放鎖會發現鎖不用等待,下一次依然能夠獲取到鎖,這就是鎖的可重入鎖性orm
不可重入鎖,與可重入鎖相反,不可遞歸調用,遞歸調用就會發生死鎖。對象