### Question:
CancellableCountDownLatch extends CountDownLatch { @Override public void await() throws InterruptedException { super.await(); if (isCancelled) { throw Optional.ofNullable(exception).orElse(new CountDownLatchCancelledException()); } } CancellableCountDownLatch(int count); void cancelWithException(RuntimeException ex); @Override void await(); @Override boolean await(long timeout, TimeUnit unit);  }### Answer:
@Test public void await() throws InterruptedException { LOGGER.info("await test"); final AtomicBoolean isThreadFinished = new AtomicBoolean(); final Executor executor = Executors.newSingleThreadExecutor(); executor.execute( () -> { LOGGER.info("await test - open latch thread: starting"); while (countDownLatch.getCount() > 0) { LOGGER.info("await test - open latch thread: counting down, {}", countDownLatch.getCount()); if (countDownLatch.getCount() == 1) { isThreadFinished.set(true); } countDownLatch.countDown(); } LOGGER.info("await test - open latch thread: finishing, {}", isThreadFinished.get()); }); LOGGER.info("await test - main thread: awaiting"); countDownLatch.await(); LOGGER.info("await test - main thread: awaited"); assertThat(isThreadFinished.get()).isTrue(); }
@Test public void awaitTimeout() throws InterruptedException { LOGGER.info("awaitTimeout test"); final AtomicBoolean isThreadFinished = new AtomicBoolean(); final Executor executor = Executors.newSingleThreadExecutor(); executor.execute( () -> { LOGGER.info("awaitTimeout test - open latch thread: starting"); while (countDownLatch.getCount() > 0) { LOGGER.info("awaitTimeout test - open latch thread: counting down, {}", countDownLatch.getCount()); if (countDownLatch.getCount() == 1) { isThreadFinished.set(true); } countDownLatch.countDown(); } isThreadFinished.set(true); }); LOGGER.info("awaitTimeout test - main thread: awaiting"); final boolean result = countDownLatch.await(100, TimeUnit.MILLISECONDS); LOGGER.info("awaitTimeout test - main thread: awaited"); assertThat(result).isTrue(); assertThat(isThreadFinished.get()).isTrue(); }
@Test public void awaitTimeoutExceeded() throws InterruptedException { final boolean result = countDownLatch.await(100, TimeUnit.MILLISECONDS); assertThat(result).isFalse(); }