Java同時プログラミング(三):Semaphoreソースコード解析


1.acquire()メソッドソース分析
 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);
        }
    }