為原始碼寫注釋 ReentrantLock

2021-08-05 20:34:21 字數 4017 閱讀 1309

reentrantlock:

先簡單講下reentrantlock裡面的成員變數。

(1)int state:用於分辨當前鎖是否已經被鎖上

1)state=0: 未上鎖

2)state>=1:已上鎖,並且state>=1時記錄的時重入鎖的次數

(2)node head:引用始終指向獲得了鎖的節點,它不會被取消。acquire操作成功就表示獲得了鎖,acquire過程中如果中斷,那麼acquire就失敗了,這時候head就會指向下乙個節點。

(3)node tail:尾節點,用於執行緒快速如佇列

先闡述公平鎖和不公平鎖的定義

公平鎖(fair):加鎖前檢查是否有排隊等待的執行緒,優先排隊等待的執行緒,先來先得

非公平鎖(nonfair):加鎖時不考慮排隊等待問題,直接嘗試獲取鎖,獲取不到自動到隊尾等待

(1)預設是構造乙個不公平的鎖。

public

reentrantlock()

(2)為true時,構造公平鎖;為false時,構造不公平鎖。

public

reentrantlock(boolean fair)

lock方法針對 fair 和 nonfair 是有不同的實現的,在下面的**的實現在於 sync 是屬於哪個鎖

public

void

lock()

(1)對於nonfairsync.lock() 的實現如下

1) 上鎖介面

final void lock()
2) 申請鎖

public

final

void

acquire(int arg)

1)嘗試快速上鎖

protected

final

boolean

tryacquire(int acquires)

final

boolean nonfairtryacquire(int acquires)

}//當前執行緒就是擁有鎖的執行緒,所以為重入鎖

else

if (current == getexclusiveownerthread())

return

false;

}

2) addwaiter: 在當前等待佇列新增成員

private node addwaiter(node mode) 

}//如果尾部節點不存在,則通過死迴圈插入佇列

enq(node);

return node;

}

3) 插入當前執行緒到 鎖等待佇列上

private node enq(final node node)  else }}

}

4) 在所等待佇列中分配鎖

final

boolean acquirequeued(final node node, int arg)

// 請求鎖失敗時,使用shouldparkafte***iledacquire判斷是否要中斷當前執行緒,需要中斷當前執行緒則呼叫parkandcheckinterrupt產生一次中斷

/**執行緒的thread.interrupt()方法是中斷執行緒,將會設定該執行緒的中斷狀態位,即設定為true,中斷的結果執行緒是死亡、還是等待新的任務或是繼續執行至下一步,就取決於這個程式本身。執行緒會不時地檢測這個中斷標示位,以判斷執行緒是否應該被中斷(中斷標示值是否為true)。它並不像stop方法那樣會中斷乙個正在執行的執行緒。*/

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

&& parkandcheckinterrupt())

interrupted = true;

}} finally

}

5) 請求鎖失敗時,是否中斷當前執行緒,這裡首先要了解node的waitstatus的定義

class:abstractqueuedsynchronizer.node

/** waitstatus value to indicate thread has cancelled:當前執行緒已登出 */

static

final

int cancelled = 1;

/** waitstatus value to indicate successor's thread needs unparking:當前執行緒的繼承者(後繼執行緒)需要喚醒*/

static

final

int signal = -1;

/** waitstatus value to indicate thread is waiting on condition:當前執行緒在等待condition喚醒*/

static

final

int condition = -2;

/** * waitstatus value to indicate the next acquireshared should:暫時不看

* unconditionally propagate

*/static

final

int propagate = -3;

private

static

boolean

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

pred.next = node;

} else

return

false;

}

6) 中斷並且檢查執行緒有沒有中斷

private

final

boolean

parkandcheckinterrupt()

7) 登出執行緒對鎖的請求

/**

* cancels an ongoing attempt to acquire.

**@param node the node

*/private

void

cancelacquire(node node) else else

node.next = node; // help gc

}}

8). next指向非null的下乙個節點,在同步佇列中等待的節點,入隊操作時設定了前乙個節點的next值,這樣可以在釋放鎖時,通知下乙個節點來獲取鎖

private void unparksuccessor(node node) 

if (s != null)

//喚醒後繼執行緒

locksupport.unpark(s.thread);

}

(1) 上鎖

final void

lock()

(2)嘗試獲取鎖

protected

final

boolean

tryacquire(int acquires)

}else

if (current == getexclusiveownerthread())

return

false;

}

(3)判斷當前佇列是否有 正在工作的節點 或 等待更久的執行緒,有就返回true

public

final

boolean

hasqueuedpredecessors()

Pytorch原始碼注釋

field類為可以由張量表示的常見文字處理資料型別建模。它包含乙個vocab物件,用於定義字段元素的可能值集及其對應的數字表示。field物件還包含與資料型別應如何數位化有關的其他引數,例如標記化方法和應生成的tensor型別。如果在資料集中的兩列之間共享字段 例如,qa資料集中的問題和答案 則它們...

devmem 原始碼注釋

include include include include include include include include include include include define fatal do while 0 define map size 4096ul define map mask...

redis原始碼注釋 簡述

second60 20180510 有些人會問 學習一門技術最快的方法是什麼?答案很簡單 就是站在巨人的肩膀上,多看多多抄多練。第一 可以省去我們造輪子,四處碰壁的時間 第二 可以學習巨人的精髓,使自已能力不斷的提公升 第三 多抄,可以使自已寫 的風格像巨人一樣,如火純青 這篇檔案不講技術,純屬非技...