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