/** * Test that an async task ({@code executeAsync()}) will block another task from running * until its {@code CompletableFuture} is completed. */ public void testConcurrencyLimitExecuteAsync() throws Exception { eventuallyEquals(0, executor::getActiveCount); LimitedExecutor limitedExecutor = new LimitedExecutor(NAME, executor, 1); CompletableFuture<String> blocker1 = new CompletableFuture<>(); CompletableFuture<String> cf1 = new CompletableFuture<>(); limitedExecutor.executeAsync(() -> blocker1.thenAccept(cf1::complete)); verifyTaskIsBlocked(limitedExecutor, blocker1, cf1); }
/** * Test that no more than 1 task runs at a time. */ public void testConcurrencyLimit() throws Exception { eventuallyEquals(0, executor::getActiveCount); LimitedExecutor limitedExecutor = new LimitedExecutor(NAME, executor, 1); CompletableFuture<String> blocker1 = new CompletableFuture<>(); CompletableFuture<String> cf1 = new CompletableFuture<>(); limitedExecutor.execute(() -> { try { cf1.complete(blocker1.get(10, SECONDS)); } catch (Exception e) { cf1.completeExceptionally(e); } }); verifyTaskIsBlocked(limitedExecutor, blocker1, cf1); }
/** * Test that an async task ({@code executeAsync()}) will block another task from running * until its {@code CompletableFuture} is completed, when using a {@link WithinThreadExecutor}. */ public void testConcurrencyLimitExecuteAsyncWithinThread() throws Exception { LimitedExecutor limitedExecutor = new LimitedExecutor(NAME, new WithinThreadExecutor(), 1); CompletableFuture<String> blocker1 = new CompletableFuture<>(); CompletableFuture<String> cf1 = new CompletableFuture<>(); // executeAsync() will not block limitedExecutor.executeAsync(() -> blocker1.thenAccept(cf1::complete)); verifyTaskIsBlocked(limitedExecutor, blocker1, cf1); }
/** * Test that no more than 1 task runs at a time when using a {@link WithinThreadExecutor}. */ public void testConcurrencyLimitWithinThread() throws Exception { LimitedExecutor limitedExecutor = new LimitedExecutor(NAME, new WithinThreadExecutor(), 1); CompletableFuture<String> blocker1 = new CompletableFuture<>(); CompletableFuture<String> blocker2 = new CompletableFuture<>(); CompletableFuture<String> cf1 = new CompletableFuture<>(); // execute() will block Future<?> fork1 = fork(() -> { limitedExecutor.execute(() -> { blocker2.complete("blocking"); try { cf1.complete(blocker1.get(10, SECONDS)); } catch (Exception e) { cf1.completeExceptionally(e); } }); }); assertEquals("blocking", blocker2.get(10, SECONDS)); verifyTaskIsBlocked(limitedExecutor, blocker1, cf1); fork1.get(10, SECONDS); }