@Override
  public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
    long endTimeNanos = System.nanoTime() + unit.toNanos(timeout);
    ArrayList<ManagedChannel> channels = new ArrayList<>();
    synchronized (this) {
      if (!shutdownStarted) {
        return false;
      }
      if (isTerminated()) {
        return true;
      }
      channels.addAll(usedChannels);
      channels.addAll(channelCache);
    }
    // Block outside the synchronized section.
    for (ManagedChannel channel : channels) {
      long awaitTimeNanos = endTimeNanos - System.nanoTime();
      if (awaitTimeNanos <= 0) {
        break;
      }
      channel.awaitTermination(awaitTimeNanos, TimeUnit.NANOSECONDS);
    }
    return isTerminated();
  }
@Test
  public void testAwaitTermination() throws Exception {
    ManagedChannel mockChannel = mock(ManagedChannel.class);
    when(channelSupplier.get()).thenReturn(mockChannel);

    IsolationChannel isolationChannel = IsolationChannel.create(channelSupplier);

    assertFalse(isolationChannel.awaitTermination(1, TimeUnit.MILLISECONDS));

    when(mockChannel.shutdown()).thenReturn(mockChannel);
    when(mockChannel.isTerminated()).thenReturn(false, false, false, true, true);
    when(mockChannel.awaitTermination(longThat(l -> l < 2_000_000), eq(TimeUnit.NANOSECONDS)))
        .thenReturn(false, true);

    isolationChannel.shutdown();
    assertFalse(isolationChannel.awaitTermination(1, TimeUnit.MILLISECONDS));
    assertTrue(isolationChannel.awaitTermination(1, TimeUnit.MILLISECONDS));

    assertTrue(isolationChannel.isTerminated());

    verify(channelSupplier, times(1)).get();
    verify(mockChannel, times(1)).shutdown();
    verify(mockChannel, times(5)).isTerminated();
    verify(mockChannel, times(2))
        .awaitTermination(longThat(l -> l < 2_000_000), eq(TimeUnit.NANOSECONDS));
  }