private int dowait ( boolean timed , long nanos ) throws InterruptedException , BrokenBarrierException , TimeoutException { final ReentrantLock lock = this . lock ; lock . lock ( ) ; try { // The call to trip.await() further down will release the lock while this thread blocks. // The @RetainedLocalRef annotation ensures that "g" is still a valid reference after // returning from the trip.await() call. @ RetainedLocalRef final Generation g = generation ; if ( g . broken ) throw new BrokenBarrierException ( ) ; if ( Thread . interrupted ( ) ) { breakBarrier ( ) ; throw new InterruptedException ( ) ; } int index = -- count ; if ( index == 0 ) { // tripped boolean ranAction = false ; try { final Runnable command = barrierCommand ; if ( command != null ) command . run ( ) ; ranAction = true ; nextGeneration ( ) ; return 0 ; } finally { if ( ! ranAction ) breakBarrier ( ) ; } } // loop until tripped, broken, interrupted, or timed out for ( ; ; ) { try { if ( ! timed ) trip . await ( ) ; else if ( nanos > 0L ) nanos = trip . awaitNanos ( nanos ) ; } catch ( InterruptedException ie ) { if ( g == generation && ! g . broken ) { breakBarrier ( ) ; throw ie ; } else { // We're about to finish waiting even if we had not // been interrupted, so this interrupt is deemed to // "belong" to subsequent execution. Thread . currentThread ( ) . interrupt ( ) ; } } if ( g . broken ) throw new BrokenBarrierException ( ) ; if ( g != generation ) return index ; if ( timed && nanos <= 0L ) { breakBarrier ( ) ; throw new TimeoutException ( ) ; } } } finally { lock . unlock ( ) ; } }
Main barrier code covering the various policies .