private void doWaitSpin ( ) { // pick a random sleep interval based on the number of threads spinning, so that // we should always have a thread about to wake up, but most threads are sleeping long sleep = 10000L * pool . spinningCount . get ( ) ; sleep = Math . min ( 1000000 , sleep ) ; sleep *= Math . random ( ) ; sleep = Math . max ( 10000 , sleep ) ; long start = System . nanoTime ( ) ; // place ourselves in the spinning collection; if we clash with another thread just exit Long target = start + sleep ; if ( pool . spinning . putIfAbsent ( target , this ) != null ) return ; LockSupport . parkNanos ( sleep ) ; // remove ourselves (if haven't been already) - we should be at or near the front, so should be cheap-ish pool . spinning . remove ( target , this ) ; // finish timing and grab spinningTime (before we finish timing so it is under rather than overestimated) long end = System . nanoTime ( ) ; long spin = end - start ; long stopCheck = pool . stopCheck . addAndGet ( spin ) ; maybeStop ( stopCheck , end ) ; if ( prevStopCheck + spin == stopCheck ) soleSpinnerSpinTime += spin ; else soleSpinnerSpinTime = 0 ; prevStopCheck = stopCheck ; }
perform a sleep - spin incrementing pool . stopCheck accordingly