ReentrantLock原始碼分析 筆記

2021-09-04 13:12:55 字數 3386 閱讀 2583

reentrantlock的實現原理分析

重入鎖提供了兩種實現,

怎麼理解公平和非公平呢?

反之,就是不公平的。

簡單來說公平鎖就是等待時間最長的執行緒最優先獲取鎖

非公平鎖的實現流程時序圖

原始碼分析

並且sync有兩個實現,

我們先來分析一下非公平鎖的實現::

final

void lock()

所以在這裡,是表示當前的state

由於reentrantlock是可重入鎖,

每次加鎖都會將state的值+1,

解鎖時每解一次鎖就會將state減1,

abstractqueuedsynchronizer.acquire

當多個執行緒同時進入這個方法時,

public

final

void

acquire(int arg)

ø 否則,自旋獲取鎖,並且判斷中斷標識,

ø addwaiter方法把當前執行緒封裝成node,

nonfairsync.tryacquire

protected

final

boolean

tryacquire(int acquires)

nofairtryacquire

這裡的實現邏輯類似synchroized關鍵字的偏向鎖的做法,

final

boolean nonfairtryacquire(int acquires)

}else

if (current == getexclusiveownerthread())

//如果狀態不為0,且當前執行緒不是owner,則返回false。

return

false; //獲取鎖失敗,返回false

}

addwaiter

private node addwaiter(node mode) 

}enq(node); // 如果隊列為null或者cas設定新的tail失敗

return node;

}

enq

private node enq(final node node)  else }}

}

**執行到這裡,aqs佇列的結構就是這樣乙個表現::

這個方法主要用於爭搶鎖

final

boolean acquirequeued(final node node, int arg)

//如果獲取鎖失敗,則根據節點的waitstatus決定是否需要掛起執行緒

if (shouldparkafte***iledacquire(p, node) &&

parkandcheckinterrupt())// 若前面為true,則執行掛起,待下次喚醒的時候檢測中斷的標誌

interrupted = true;

}} finally

}

原來的head節點釋放鎖以後,會從佇列中移除,

對於第三個及以後的節點,if (p == head)條件不成立,

方法是判斷乙個爭用鎖的執行緒是否應該被阻塞。

所以它可以安全的阻塞了,返回true

private

static

boolean

shouldparkafte***iledacquire(node pred, node node) while (pred.waitstatus > 0);

pred.next = node;

} else

return

false;

}

解讀:假如有t1,t2兩個執行緒都加入到了鍊錶中

而head以及thread1的的awaitstatus都是signal,

signal:值為-1,

condition:值為-2,

propagate:值為-3,

parkandcheckinterrupt

它是通過locksupport.park(this)將當前執行緒掛起到wating狀態,

private

final

boolean

parkandcheckinterrupt()

reentrantlock.unlock

public

final

boolean

release(int arg)

return

false;

}

tryrelease

在排它鎖中,加鎖的時候狀態會增加1(當然可以自己修改這個值),

在解鎖的時候減掉1,同乙個鎖,在可以重入後,可能會被疊加為2、3、4這些值,

protected

final

boolean

tryrelease(int releases)

setstate(c);

return free;

}

unparksuccessor

private

void

unparksuccessor(node node)

if (s != null)

locksupport.unpark(s.thread);

}

locksupport.unpark(s.thread);

unpark函式為執行緒提供「許可(permit)」,

permit相當於0/1的開關,預設是0,

這時呼叫unpark會把permit設定為1.

在使用locksupport之前,

總結移出佇列(或停止自旋)的條件是

在釋放同步狀態時,同步器呼叫tryrelease(int arg)方法釋放同步狀態,

AbstractCollection原始碼分析

abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...

ThreadPoolExecutor原始碼閱讀

執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...

OrangePi One Android 原始碼編譯

一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...