private void idleAwaitWork ( WorkQueue w , long currentCtl , long prevCtl ) { if ( w . eventCount < 0 && ! tryTerminate ( false , false ) && ( int ) prevCtl != 0 && ! hasQueuedSubmissions ( ) && ctl == currentCtl ) { Thread wt = Thread . currentThread ( ) ; Thread . yield ( ) ; // yield before block while ( ctl == currentCtl ) { long startTime = System . nanoTime ( ) ; Thread . interrupted ( ) ; // timed variant of version in scan() U . putObject ( wt , PARKBLOCKER , this ) ; w . parker = wt ; if ( ctl == currentCtl ) U . park ( false , SHRINK_RATE ) ; w . parker = null ; U . putObject ( wt , PARKBLOCKER , null ) ; if ( ctl != currentCtl ) break ; if ( System . nanoTime ( ) - startTime >= SHRINK_TIMEOUT && U . compareAndSwapLong ( this , CTL , currentCtl , prevCtl ) ) { w . eventCount = ( w . eventCount + E_SEQ ) | E_MASK ; w . runState = - 1 ; // shrink break ; } } } }
If inactivating worker w has caused the pool to become quiescent checks for pool termination and so long as this is not the only worker waits for event for up to SHRINK_RATE nanosecs . On timeout if ctl has not changed terminates the worker which will in turn wake up another worker to possibly repeat this process .