當前位置:科普知識站>IT科技>

java|reentrantlock

IT科技 閱讀(2.1W)

<link rel="stylesheet" href="https://js.how234.com/third-party/SyntaxHighlighter/shCoreDefault.css" type="text/css" /><script type="text/javascript" src="https://js.how234.com/third-party/SyntaxHighlighter/shCore.js"></script><script type="text/javascript"> SyntaxHighlighter.all(); </script>

java reentrantlock是什麼?一起來看下吧:

是一個可重入且獨佔式的鎖,它具有與使用synchronized監視器鎖相同的基本行為和語義,但與synchronized關鍵字相比,它更靈活、更強大,增加了輪詢、超時、中斷等高階功能。ReentrantLock,顧名思義,它是支援可重入鎖的鎖,是一種遞迴無阻塞的同步機制。除此之外,該鎖還支援獲取鎖時的公平和非公平選擇。

ReentrantLock的內部類Sync繼承了AQS,分為公平鎖FairSync和非公平鎖NonfairSync。如果在絕對時間上,先對鎖進行獲取的請求你一定先被滿足,那麼這個鎖是公平的,反之,是不公平的。公平鎖的獲取,也就是等待時間最長的執行緒最優先獲取鎖,也可以說鎖獲取是順序的。ReentrantLock的公平與否,可以通過它的建構函式來決定。

事實上,公平鎖往往沒有非公平鎖的效率高,但是,並不是任何場景都是以TPS作為唯一指標,公平鎖能夠減少“飢餓”發生的概率,等待越久的請求越能夠得到優先滿足。

ReentrantLock是通過自定義同步器來實現鎖的獲取與釋放,我們以非公平鎖(預設)實現為例,對鎖的獲取和釋放進行詳解。

獲取鎖:

public ReentrantLock() {    sync = new NonfairSync();}

即內部同步元件為非公平鎖,獲取鎖的程式碼為:

public void lock() {    sync.lock();}

釋放鎖:

成功獲取鎖的執行緒在完成業務邏輯之後,需要呼叫unlock()來釋放鎖:

public void unlock() {    sync.release(1);}

unlock()呼叫NonfairSync類的release(int)方法釋放鎖,release(int)方法是定義在AQS中的方法:

public final boolean release(int arg) {    if (tryRelease(arg)) {        Node h = head;        if (h != null && h.waitStatus != 0)            unparkSuccessor(h);        return true;    }    return false;}

tryRelease(int)是子類需要實現的方法:

protected final boolean tryRelease(int releases) {    // 計算新的狀態值    int c = getState() - releases;    // 判斷當前執行緒是否是持有鎖的執行緒,如果不是的話,丟擲異常    if (Thread.currentThread() != getExclusiveOwnerThread())        throw new IllegalMonitorStateException();    boolean free = false;    // 新的狀態值是否為0,若為0,則表示該鎖已經完全釋放了,其他執行緒可以獲取同步狀態了    if (c == 0) {        free = true;        setExclusiveOwnerThread(null);    }    // 更新狀態值    setState(c);    return free;}

如果該鎖被獲取n次,那麼前(n-1)次tryRelease(int)方法必須返回false,只有同步狀態完全釋放了,才能返回true。可以看到,該方法將同步狀態是否為0作為最終釋放的條件,當狀態為0時,將佔有執行緒設為null,並返回true,表示釋放成功。

java reentrantlock