1. 類的定義
public class CountDownLatch
複製程式碼
2. 欄位屬性
//同步器,是AbstractQueuedSynchronizer的子類
private final Sync sync;
複製程式碼
從欄位屬性可以看出
- CountDownLatch的核心是內部類Sync,可以猜測出所有的操作都是通過Sync物件來操作的
3. 構造方法
public CountDownLatch(int count) {
//引數檢查
if (count < 0) throw new IllegalArgumentException("count < 0");
//初始化Sync
this.sync = new Sync(count);
}
複製程式碼
從構造方法中可以看出
- 構造方法只做了一件事就是初始化Sync物件
4. 方法
await 方法
//等待,直到count到0再執行,或者執行緒被中斷
public void await() throws InterruptedException {
//呼叫sync的acquireSharedInterruptibly方法進入等待
sync.acquireSharedInterruptibly(1);
}
//設定超時時間的等待
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
//呼叫sync的tryAcquireSharedNanos方法進入等待
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
複製程式碼
countDown 方法
//count 減1
public void countDown() {
//呼叫sync的releaseShared方法
sync.releaseShared(1);
}
複製程式碼
getCount 方法
//獲取count
public long getCount() {
//呼叫sync的getCount
return sync.getCount();
}
複製程式碼
toString 方法
public String toString() {
//可以看出列印了count的值
return super.toString() + "[Count = " + sync.getCount() + "]";
}
複製程式碼
從方法中可以看出Sync物件是一個共享鎖
5. 內部類Sync
1. 類的定義
private static final class Sync extends AbstractQueuedSynchronizer
複製程式碼
從類的定義中可以看出
- Sync是CountDownLatch私有的靜態內部類
- Sync繼承了AbstractQueuedSynchronizer
2. 欄位屬性
//序列化版本號
private static final long serialVersionUID = 4982264981922014374L;
複製程式碼
3. 構造方法
//傳入count
Sync(int count) {
//呼叫父類的setState方法
setState(count);
}
複製程式碼
從構造方法可以看出
- 傳入的count就是AbstractQueuedSynchronizer的state方法
4. 方法
getCount 方法
//獲取count,實際上就是獲取state
int getCount() {
return getState();
}
複製程式碼
tryAcquireShared 方法
//嘗試獲取共享鎖,重寫父類方法,這個方法是讓父類呼叫
protected int tryAcquireShared(int acquires) {
//如果state為0,返回1, 其他的返回-1
//小於0會嘗試獲取鎖,如果獲取鎖失敗則會進入佇列等待被喚醒
return (getState() == 0) ? 1 : -1;
}
複製程式碼
tryReleaseShared 方法
//釋放共享鎖,這個引數沒有意義,每次通過CAS自旋的方法讓state-1
protected boolean tryReleaseShared(int releases) {
//無限for迴圈表示自旋
for (;;) {
//獲取狀態值
int c = getState();
//如果狀態值為0, 表示已經完全釋放鎖了,直接返回false
if (c == 0)
return false;
//狀態值不為0,讓狀態值-1,並用CAS設定新值
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
複製程式碼