@Test
public void testMultiThreadBoundedConcurrency()
        throws Exception
{

    AsyncSemaphore<Runnable> asyncSemaphore = new AsyncSemaphore<>(2, executor, executor::submit);
    final AtomicInteger count = new AtomicInteger();
    final AtomicInteger concurrency = new AtomicInteger();
    List<ListenableFuture<?>> futures = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        futures.add(asyncSemaphore.submit(() -> {
            count.incrementAndGet();
            int currentConcurrency = concurrency.incrementAndGet();
            assertLessThanOrEqual(currentConcurrency, 2);
            Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MILLISECONDS);
            concurrency.decrementAndGet();
        }));
    }
    // Wait for completion
    Futures.allAsList(futures).get(1, TimeUnit.MINUTES);
    Assert.assertEquals(count.get(), 1000);
}