StoppableCountDownLatch { public void await() throws InterruptedException { do { stopper.checkCancelInProgress(null); } while (!delegate.await(retryIntervalNanos, NANOSECONDS)); } StoppableCountDownLatch(final CancelCriterion stopper, final int count);   StoppableCountDownLatch(final CancelCriterion stopper, final int count,
      final long retryIntervalNanos, final NanoTimer nanoTimer); void await(); boolean await(final long timeout, final TimeUnit unit); boolean await(final long timeoutMillis); void countDown(); long getCount(); @Override String toString();  }
@Test public void awaitWithTimeoutAndTimeUnitReturnsFalseAfterTimeout() throws Exception { StoppableCountDownLatch latch = new StoppableCountDownLatch(stopper, 1, MILLISECONDS.toNanos(2), System::nanoTime); long theTimeoutMillis = 2; long startNanos = System.nanoTime(); Future<Boolean> latchFuture = executorServiceRule.submit(() -> latch.await(theTimeoutMillis, MILLISECONDS)); assertThat(latchFuture.get(TIMEOUT_MILLIS, MILLISECONDS)).isFalse(); assertThat(System.nanoTime() - startNanos).isGreaterThanOrEqualTo(theTimeoutMillis); }
@Test public void awaitWithTimeoutMillisReturnsFalseAfterTimeout() throws Exception { StoppableCountDownLatch latch = new StoppableCountDownLatch(stopper, 1, MILLISECONDS.toNanos(2), System::nanoTime); long theTimeoutMillis = 2; long startNanos = System.nanoTime(); Future<Boolean> latchFuture = executorServiceRule.submit(() -> latch.await(theTimeoutMillis)); assertThat(latchFuture.get(TIMEOUT_MILLIS, MILLISECONDS)).isFalse(); assertThat(System.nanoTime() - startNanos).isGreaterThanOrEqualTo(theTimeoutMillis); }