3.8 ReentrandLock
故名思意,ReentrandLock即可重入鎖,可重入鎖解決的是重入鎖定的問題,重入鎖定(Reentrance Lockout)指的是當一個執行緒執行邏輯時,需要兩次獲取鎖,而該鎖不可重入就會導致內部嵌套無法獲取鎖導致Reentrance Lockout發生,Reentrance Lockout解決辦法為一個執行緒兩次獲取鎖的中間一定需要釋放鎖,
3.8.1 ReentrandLock繼承關系
此處知道ReentrandLock是Lock介面的實作即可,

3.8.2 ReentradLock使用
宣告鎖即new創建鎖,
static Lock lock = new ReentrantLock();
//修改時需要鎖定的資源
static String text = "hello";
不加鎖對text進行修改,
public static void modifyWithoutLock(){
text += " "+Thread.currentThread().getName();
}
public static void main(String[] args) throws InterruptedException {
modifyWithoutLock();
for (int i=0;i<100;i++) {
new Thread(() -> {
modifyWithoutLock();
}).start();
}
Thread.sleep(50);
System.err.println(text.length());
}
不加鎖修改后text的長度為:



可知,對一個String變數多執行緒不加鎖的情況下最后結果的長度很大概率是不一樣的,
加鎖對text進行修改,
public static void modify(){
//使用lock方法枷鎖
lock.lock();
try {
text += " "+Thread.currentThread().getName();
}catch (Exception e){
e.printStackTrace();
}
finally {
//使用unlock方法解鎖
lock.unlock();
}
}

加鎖之后對多執行緒對text的修改最后的長度是一定的(這兒不能保證執行緒修改的順序),
3.8.2 ReentradLock方法介紹
| ReentrandLock | 作用 |
|---|---|
| tryLock() | 嘗試獲取鎖 |
| tryLock(long timeout, TimeUnit unit) | 嘗試獲取鎖,timeout是嘗試獲取鎖的等待事件,超時不候,unit是等待時間的單位 |
| unlock() | 釋放鎖 |
| getHoldCount() | 當前執行緒持有該鎖的次數 |
| isHeldByCurrentThread() | 當前執行緒是否持有該鎖 |
| … | … |
3.8.3 ReentrandLock原始碼
構造方法
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
* 如果fair為true則構造是一個公平鎖
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
ReentrandLock默認是非公平鎖,也可以通過傳入一個boolean fair的引數構造來宣告該鎖是公平鎖還是非公平鎖,
內部組成

private final Sync sync;
其內部由一個Sync sync屬性組成,其是ReentradLock的內部類,Sync抽象內有NonfairSync和FairSync兩種子類實作,分別表示非公平鎖和公平鎖,
加解鎖方法
public void lock() {
sync.lock();
}
public void unlock() {
sync.release(1);
}
其具體實作其實是Sync的子類FairSync或者NonfairSync的方法,具體使用的哪個看構造的時候是公平鎖還是非公平鎖,對于Sync的決議放在后邊再說,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/258711.html
標籤:java
上一篇:aliyun-oss-02
下一篇:「JavaDay19」例外與檔案
