1. 程式人生 > >JUC程式碼淺析[4]——基於AQS的訊號量Semaphore

JUC程式碼淺析[4]——基於AQS的訊號量Semaphore

JUC程式碼淺析[4]——基於AQS的訊號量Semaphore

Semaphore是基於AQS共享模式實現的計數訊號量,它維護一個資源一個時期內最多訪問者個數。超過限制數量的執行緒被阻塞。使用state表示許可的個數。acquire操作減少計數,release增加計數,許可計數為0時就不允許新的訪問進入。

獲取許可,

publicvoid acquire() throws InterruptedException {

//acquireSharedInterruptibly方法參考AQS的介紹

sync.acquireSharedInterruptibly(1);

}

訊號量sync也分為公平和非公平的實現,其中非公平

sync,剩餘許可小於0時執行緒就進入佇列阻塞等待AQS排程

protectedint tryAcquireShared(int acquires) {

return nonfairTryAcquireShared(acquires);

}

finalint nonfairTryAcquireShared(int acquires) {

for (;;) {

int available = getState();

int remaining = available - acquires;

if (remaining < 0 ||

compareAndSetState(available, remaining))

return remaining;

}

}

公平sync,只要當前執行緒不處於AQS佇列的首位就進入佇列阻塞等待排程,在首位時跟非公平一樣

protectedint tryAcquireShared(int acquires) {

Thread current = Thread.currentThread();

for (;;) {

Thread first = getFirstQueuedThread();

if (first != null && first != current)

return -1;

int available = getState();

int remaining = available - acquires;

if (remaining < 0 ||

compareAndSetState(available, remaining))

return remaining;

}

}

釋放許可,比較簡單,增加許可

protectedfinalboolean tryReleaseShared(int releases) {

for (;;) {

int p = getState();

if (compareAndSetState(p, p + releases))

returntrue;

}

}