ReentrantLock解鎖流程

2021-10-08 14:11:11 字數 1278 閱讀 2382

上篇介紹了reentrantlock的加速流程,傳送門: 有加鎖就有解鎖,接下來**一下解鎖的流程。解鎖流程總體來說比這加鎖簡單。先上流程圖:

解鎖流程從呼叫lock.unlock()開始,lock.unlock()方法呼叫的是sync.release(1)方法,sync.release(1)的**如下:

public final boolean release(int arg) 

return false;

}

release(int arg) 方法是sync的父類abstractqueuedsynchronizer實現的,其呼叫了tryrelease(arg),tryrelease(arg)跟tryaquire一樣,在aqs裡面 沒有具體實現,需要子類實現,下面貼出reentrantlock的tryrelease(arg) 的**:

protected final boolean tryrelease(int releases) 

//當c == 0時,這一步執行完,該執行緒就真正釋放了鎖,其他執行緒就可以擁有鎖了,

//因為還沒有執行unpark方法,還沒有喚醒該執行緒的後繼節點的執行緒,

//所以在非公平鎖的情況下,未入隊的執行緒比這等待佇列裡的執行緒更容易競爭到鎖

setstate(c);

return free;

}

tryrelease後,(若鎖的狀態為0(即state == 0)&& 等待佇列不為空 && head.waitstatus != 0) 就可以喚醒head的後繼節點。關於waitstatues !=0 這個條件,這裡做一下簡要說明:waitstatus ==0 時,改節點的後繼節點還沒有park所以不需要unpark。下面看一下unparksuccessor(h)的**:

private void unparksuccessor(node node) 

if (s != null)

locksupport.unpark(s.thread);

}

unparksuccessor是aqs的乙個私有方法,只能該類內部呼叫。當呼叫完locksupport.unpark(s.thread)方法後,喚醒在park狀態的執行緒s.thread。喚醒不等於擁有鎖,因為s.thread被喚醒後需要通過tryacquire() 方法去競爭,如果競爭失敗則在競爭一次如果兩次都沒有競爭則繼續阻塞,等著獲取的執行緒再次喚醒自己。

從ReentrantLock加鎖解鎖角度分析AQS

本文用於記錄在學習aqs時,以reentrantlock為切入點,深入原始碼分析reentrantlock的加鎖和解鎖過程。同步器aqs的主要使用方式是繼承,子類通過繼承同步器並實現它的抽象方法來管理同步狀態 通常鎖或者同步元件內部會實現乙個sync類 該類是乙個靜態內部類 然後讓sync類去繼承a...

ReentrantLock實現同步

reentrantlock 也可以實現synchronized方法 塊的同步效果。reentrantlock 實現同步 如下 1 新建乙個service類 public class myservice public static void methodb 2 新建乙個測試類 public class...

ReentrantLock之unlock方法分析

public void unlock public final boolean release int arg return false release 1 嘗試在當前鎖的鎖定計數 state 值上減1。成功返回true,否則返回false。當然在release 方法中不僅僅只是將state 1這麼...