Java同時プログラミング(三):Semaphoreソースコード解析
1.acquire()メソッドソース分析
NonfairSyncはSemaphoreの内部クラスNonfairSyncがSyncから継承され、SyncがAbstractQueuedSynchronizer nonfairTryAcquireSharedがSyncのメソッドから継承されます.
acquireSharedInterruptibly()メソッドに戻り、残りのロックが0未満の場合、doAcquireSharedInterruptibly(arg);
public void acquire() throws InterruptedException {
//sync Semaphore
sync.acquireSharedInterruptibly(1);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
// , 0 , ,
// 0, doAcquireSharedInterruptibly(),
// tryAcquireShared() 。NonfairSync
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
NonfairSyncはSemaphoreの内部クラスNonfairSyncがSyncから継承され、SyncがAbstractQueuedSynchronizer nonfairTryAcquireSharedがSyncのメソッドから継承されます.
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState(); //
// ,
int remaining = available - acquires;
// <0, 。
// >=0, , 。
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
acquireSharedInterruptibly()メソッドに戻り、残りのロックが0未満の場合、doAcquireSharedInterruptibly(arg);
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
// , 。
int r = tryAcquireShared(arg);
if (r >= 0) {
// , ,
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
// ,
if (shouldParkAfterFailedAcquire(p, node) &&
// , countDownLatch ; , , CPU
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}