Semaphore原始碼解析
Semaphore
用來控制同時訪問特定資源的執行緒數量,使用 AQS
狀態值 state
代表許可數 permits
。
構造方法引數:
permits
:許可數fair
:是否公平訊號量
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
首先來分析 acquire
獲取鎖方法
// Semaphore
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
以共享可中斷方式獲取鎖
// AbstractQueuedSynchronizer
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
非公平方式獲取共享鎖
// Semaphore.NonfairSync
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
// Semaphore.Sync
final int nonfairTryAcquireShared(int acquires) {
// 迴圈
for (;;) {
int available = getState(); // 獲取當前狀態值(許可數)
int remaining = available - acquires; // 剩餘可用許可數減去需要許可數
// 如果剩餘可用許可數小於0 或 CAS設定當前剩餘可用許可數成功,則返回剩餘可用許可數
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
公平方式獲取共享鎖,新增 hasQueuedPredecessors
方法判斷是否有先與當前執行緒獲取鎖的執行緒
// Semaphore.FairSync
protected int tryAcquireShared(int acquires) {
for (;;) {
// 新增判斷是否有先與當前執行緒獲取鎖的執行緒
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
分析 release
釋放鎖方法
// Semaphore
public void release() {
sync.releaseShared(1);
}
// AbstractQueuedSynchronizer
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
// Semaphore.Sync
protected final boolean tryReleaseShared(int releases) {
for (;;) {
int current = getState(); // 獲取當前狀態值(許可數)
int next = current + releases; // 當前剩餘可用許可數加上本地釋放許可數
if (next < current) // overflow
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next)) // CAS設定狀態值(許可數)
return true;
}
}
相關文章
- 深入淺出Semaphore原始碼解析原始碼
- Semaphore訊號量原始碼解析原始碼
- Java併發之Semaphore原始碼解析(一)Java原始碼
- Java併發之Semaphore原始碼解析(二)Java原始碼
- java原始碼-SemaphoreJava原始碼
- Semaphore原始碼分析原始碼
- Java併發包原始碼學習系列:同步元件Semaphore原始碼解析Java原始碼元件
- Semaphore解析
- 原始碼分析:Semaphore之訊號量原始碼
- 併發工具類:Semaphore原始碼解讀原始碼
- 第 57 期 sync/semaphore 原始碼淺析原始碼
- Semaphore最詳細解析
- Redisson 分散式鎖原始碼 11:Semaphore 和 CountDownLatchRedis分散式原始碼CountDownLatch
- go中semaphore(訊號量)原始碼解讀Go原始碼
- Java 併發程式設計(十五) -- Semaphore原始碼分析Java程式設計原始碼
- 多執行緒基礎(十九):Semaphore原始碼分析執行緒原始碼
- Java Timer原始碼解析(定時器原始碼解析)Java原始碼定時器
- 【原始碼解析】- ArrayList原始碼解析,絕對詳細原始碼
- ReactNative原始碼解析-初識原始碼React原始碼
- Koa 原始碼解析原始碼
- Koa原始碼解析原始碼
- RxPermission原始碼解析原始碼
- Express原始碼解析Express原始碼
- redux原始碼解析Redux原始碼
- CopyOnWriteArrayList原始碼解析原始碼
- LeakCanary原始碼解析原始碼
- ArrayBlockQueue原始碼解析BloC原始碼
- ReentrantLock原始碼解析ReentrantLock原始碼
- OKio原始碼解析原始碼
- ReentrantReadWriteLock原始碼解析原始碼
- CyclicBarrier原始碼解析原始碼
- Exchanger原始碼解析原始碼
- SDWebImage原始碼解析Web原始碼
- AbstractQueuedSynchronizer原始碼解析原始碼
- LinkedList原始碼解析原始碼
- HandlerThread原始碼解析thread原始碼
- ButterKnife原始碼解析原始碼
- SpringMVC原始碼解析SpringMVC原始碼