Search in sources :

Example 1 with CompletableFuture.completedFuture

use of java8.util.concurrent.CompletableFuture.completedFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testManyDependents.

/**
 * A single CompletableFuture with many dependents.
 * A demo of scalability - runtime is O(n).
 */
public void testManyDependents() throws Throwable {
    final int n = expensiveTests ? 1_000_000 : 10;
    final CompletableFuture<Void> head = new CompletableFuture<>();
    final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void) null);
    final AtomicInteger count = new AtomicInteger(0);
    for (int i = 0; i < n; i++) {
        head.thenRun(() -> count.getAndIncrement());
        head.thenAccept(x -> count.getAndIncrement());
        head.thenApply(x -> count.getAndIncrement());
        head.runAfterBoth(complete, () -> count.getAndIncrement());
        head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement());
        head.thenCombine(complete, (x, y) -> count.getAndIncrement());
        complete.runAfterBoth(head, () -> count.getAndIncrement());
        complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement());
        complete.thenCombine(head, (x, y) -> count.getAndIncrement());
        head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement());
        head.acceptEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
        head.applyToEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
        new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement());
        new CompletableFuture<Void>().acceptEither(head, x -> count.getAndIncrement());
        new CompletableFuture<Void>().applyToEither(head, x -> count.getAndIncrement());
    }
    head.complete(null);
    assertEquals(5 * 3 * n, count.get());
}
Also used : CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 2 with CompletableFuture.completedFuture

use of java8.util.concurrent.CompletableFuture.completedFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testRejectingExecutor.

/**
 * Test submissions to an executor that rejects all tasks.
 */
public void testRejectingExecutor() {
    for (Integer v : new Integer[] { 1, null }) {
        final CountingRejectingExecutor e = new CountingRejectingExecutor();
        final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
        List<CompletableFuture<?>> futures = new ArrayList<>();
        List<CompletableFuture<Integer>> srcs = new ArrayList<>();
        srcs.add(complete);
        srcs.add(incomplete);
        for (CompletableFuture<Integer> src : srcs) {
            List<CompletableFuture<?>> fs = new ArrayList<>();
            fs.add(src.thenRunAsync(() -> {
            }, e));
            fs.add(src.thenAcceptAsync(z -> {
            }, e));
            fs.add(src.thenApplyAsync(z -> z, e));
            fs.add(src.thenCombineAsync(src, (x, y) -> x, e));
            fs.add(src.thenAcceptBothAsync(src, (x, y) -> {
            }, e));
            fs.add(src.runAfterBothAsync(src, () -> {
            }, e));
            fs.add(src.applyToEitherAsync(src, z -> z, e));
            fs.add(src.acceptEitherAsync(src, z -> {
            }, e));
            fs.add(src.runAfterEitherAsync(src, () -> {
            }, e));
            fs.add(src.thenComposeAsync(z -> null, e));
            fs.add(src.whenCompleteAsync((z, t) -> {
            }, e));
            fs.add(src.handleAsync((z, t) -> null, e));
            for (CompletableFuture<?> future : fs) {
                if (src.isDone())
                    checkCompletedWithWrappedException(future, e.ex);
                else
                    checkIncomplete(future);
            }
            futures.addAll(fs);
        }
        {
            List<CompletableFuture<?>> fs = new ArrayList<>();
            fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e));
            fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e));
            fs.add(complete.thenAcceptBothAsync(incomplete, (x, y) -> {
            }, e));
            fs.add(incomplete.thenAcceptBothAsync(complete, (x, y) -> {
            }, e));
            fs.add(complete.runAfterBothAsync(incomplete, () -> {
            }, e));
            fs.add(incomplete.runAfterBothAsync(complete, () -> {
            }, e));
            for (CompletableFuture<?> future : fs) checkIncomplete(future);
            futures.addAll(fs);
        }
        {
            List<CompletableFuture<?>> fs = new ArrayList<>();
            fs.add(complete.applyToEitherAsync(incomplete, z -> z, e));
            fs.add(incomplete.applyToEitherAsync(complete, z -> z, e));
            fs.add(complete.acceptEitherAsync(incomplete, z -> {
            }, e));
            fs.add(incomplete.acceptEitherAsync(complete, z -> {
            }, e));
            fs.add(complete.runAfterEitherAsync(incomplete, () -> {
            }, e));
            fs.add(incomplete.runAfterEitherAsync(complete, () -> {
            }, e));
            for (CompletableFuture<?> future : fs) checkCompletedWithWrappedException(future, e.ex);
            futures.addAll(fs);
        }
        incomplete.complete(v);
        for (CompletableFuture<?> future : futures) checkCompletedWithWrappedException(future, e.ex);
        assertEquals(futures.size(), e.count.get());
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Arrays(java.util.Arrays) Test(junit.framework.Test) TimeoutException(java.util.concurrent.TimeoutException) Callable(java.util.concurrent.Callable) CompletableFuture.completedFuture(java8.util.concurrent.CompletableFuture.completedFuture) Predicate(java8.util.function.Predicate) AtomicReference(java.util.concurrent.atomic.AtomicReference) CompletableFuture.failedFuture(java8.util.concurrent.CompletableFuture.failedFuture) Function(java8.util.function.Function) ArrayList(java.util.ArrayList) TestSuite(junit.framework.TestSuite) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) BiFunction(java8.util.function.BiFunction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Consumer(java8.util.function.Consumer) ForkJoinPool(java8.util.concurrent.ForkJoinPool) Method(java.lang.reflect.Method) CompletionStage(java8.util.concurrent.CompletionStage) Objects(java8.util.Objects) CancellationException(java.util.concurrent.CancellationException) Executor(java.util.concurrent.Executor) ForkJoinTask(java8.util.concurrent.ForkJoinTask) Set(java.util.Set) Collectors(java8.util.stream.Collectors) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) StreamSupport(java8.util.stream.StreamSupport) Supplier(java8.util.function.Supplier) ExecutionException(java.util.concurrent.ExecutionException) List(java.util.List) CompletableFuture(java8.util.concurrent.CompletableFuture) BiConsumer(java8.util.function.BiConsumer) RefStreams(java8.util.stream.RefStreams) Modifier(java.lang.reflect.Modifier) CompletionException(java8.util.concurrent.CompletionException) SECONDS(java.util.concurrent.TimeUnit.SECONDS) CompletableFuture(java8.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with CompletableFuture.completedFuture

use of java8.util.concurrent.CompletableFuture.completedFuture in project streamsupport by stefan-zobel.

the class Basic method test.

private static void test(ExecutorService executor) throws Throwable {
    Thread.currentThread().setName("mainThread");
    // ----------------------------------------------------------------
    try {
        CompletableFuture<String> cf = supplyAsync(() -> "a test string");
        checkCompletedNormally(cf, cf.join());
        cf = supplyAsync(() -> "a test string", commonPool());
        checkCompletedNormally(cf, cf.join());
        cf = supplyAsync(() -> "a test string", executor);
        checkCompletedNormally(cf, cf.join());
        cf = supplyAsync(() -> {
            throw new RuntimeException();
        });
        checkCompletedExceptionally(cf);
        cf = supplyAsync(() -> {
            throw new RuntimeException();
        }, commonPool());
        checkCompletedExceptionally(cf);
        cf = supplyAsync(() -> {
            throw new RuntimeException();
        }, executor);
        checkCompletedExceptionally(cf);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf = runAsync(() -> {
        });
        checkCompletedNormally(cf, cf.join());
        cf = runAsync(() -> {
        }, commonPool());
        checkCompletedNormally(cf, cf.join());
        cf = runAsync(() -> {
        }, executor);
        checkCompletedNormally(cf, cf.join());
        cf = runAsync(() -> {
            throw new RuntimeException();
        });
        checkCompletedExceptionally(cf);
        cf = runAsync(() -> {
            throw new RuntimeException();
        }, commonPool());
        checkCompletedExceptionally(cf);
        cf = runAsync(() -> {
            throw new RuntimeException();
        }, executor);
        checkCompletedExceptionally(cf);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        final Phaser phaser = new Phaser(1);
        final int phase = phaser.getPhase();
        CompletableFuture<Integer> cf;
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase);
            return 1;
        });
        cf.complete(2);
        phaser.arrive();
        checkCompletedNormally(cf, 2);
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase + 1);
            return 1;
        });
        cf.completeExceptionally(new Throwable());
        phaser.arrive();
        checkCompletedExceptionally(cf);
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase + 2);
            return 1;
        });
        cf.cancel(true);
        phaser.arrive();
        checkCompletedExceptionally(cf, true);
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase + 3);
            return 1;
        });
        check(cf.getNow(2) == 2);
        phaser.arrive();
        checkCompletedNormally(cf, 1);
        check(cf.getNow(2) == 1);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<String> cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenApply(x -> x.equals("a test string") ? 1 : 0);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, 1);
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenApplyAsync(x -> x.equals("a test string") ? 1 : 0);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, 1);
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenApplyAsync(x -> x.equals("a test string") ? 1 : 0, executor);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, 1);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenApply(x -> 0);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenApplyAsync(x -> 0);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenApplyAsync(x -> 0, executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf2;
        int before = atomicInt.get();
        CompletableFuture<String> cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenAccept(x -> {
            if (x.equals("a test string")) {
                atomicInt.incrementAndGet();
                return;
            }
            throw new RuntimeException();
        });
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenAcceptAsync(x -> {
            if (x.equals("a test string")) {
                atomicInt.incrementAndGet();
                return;
            }
            throw new RuntimeException();
        });
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenAcceptAsync(x -> {
            if (x.equals("a test string")) {
                atomicInt.incrementAndGet();
                return;
            }
            throw new RuntimeException();
        }, executor);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenAccept(x -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenAcceptAsync(x -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenAcceptAsync(x -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf2;
        int before = atomicInt.get();
        CompletableFuture<String> cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenRun(() -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet(), executor);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenRun(() -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf3;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombine(cf2, (x, y) -> x + y);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> x + y);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> x + y, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombine(cf2, (x, y) -> 0);
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 1);
        checkCompletedExceptionally(cf3);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> 0);
        checkCompletedNormally(cf1, 1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> 0, executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBoth(cf2, (x, y) -> {
            check(x + y == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> {
            check(x + y == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> {
            check(x + y == 2);
            atomicInt.incrementAndGet();
        }, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBoth(cf2, (x, y) -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 1);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf1, 1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 1);
        cf3 = cf1.runAfterBoth(cf2, () -> {
            check(cf1.isDone());
            check(cf2.isDone());
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        CompletableFuture<Integer> cfa = supplyAsync(() -> 1);
        CompletableFuture<Integer> cfb = supplyAsync(() -> 1);
        cf3 = cfa.runAfterBothAsync(cfb, () -> {
            check(cfa.isDone());
            check(cfb.isDone());
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cfa, 1);
        checkCompletedNormally(cfb, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        CompletableFuture<Integer> cfx = supplyAsync(() -> 1);
        CompletableFuture<Integer> cfy = supplyAsync(() -> 1);
        cf3 = cfy.runAfterBothAsync(cfx, () -> {
            check(cfx.isDone());
            check(cfy.isDone());
            atomicInt.incrementAndGet();
        }, executor);
        checkCompletedNormally(cfx, 1);
        checkCompletedNormally(cfy, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        CompletableFuture<Integer> cf4 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        CompletableFuture<Integer> cf5 = supplyAsync(() -> 1);
        cf3 = cf5.runAfterBothAsync(cf4, () -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf4);
        checkCompletedNormally(cf5, 1);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        before = atomicInt.get();
        cf4 = supplyAsync(() -> 1);
        cf5 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf5.runAfterBothAsync(cf4, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf4, 1);
        checkCompletedExceptionally(cf5);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        before = atomicInt.get();
        cf4 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf5 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf5.runAfterBoth(cf4, () -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf4);
        checkCompletedExceptionally(cf5);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf3;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEither(cf2, x -> {
            check(x == 1 || x == 2);
            return x;
        });
        checkCompletedNormally(cf3, new Object[] { 1, 2 });
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1 || x == 2);
            return x;
        });
        checkCompletedNormally(cf3, new Object[] { 1, 2 });
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1 || x == 2);
            return x;
        }, executor);
        checkCompletedNormally(cf3, new Object[] { 1, 2 });
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEither(cf2, x -> {
            check(x == 2);
            return x;
        });
        try {
            check(cf3.join() == 2);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1);
            return x;
        });
        try {
            check(cf3.join() == 1);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            fail();
            return x;
        });
        checkCompletedExceptionally(cf3);
        check(cf1.isDone() || cf2.isDone());
        final Phaser cf3Done = new Phaser(2);
        cf1 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 1;
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEither(cf2, x -> {
            check(x == 2);
            return x;
        });
        checkCompletedNormally(cf3, 2);
        checkCompletedNormally(cf2, 2);
        check(!cf1.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 2;
        });
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1);
            return x;
        });
        checkCompletedNormally(cf3, 1);
        checkCompletedNormally(cf1, 1);
        check(!cf2.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf2, 2);
        checkCompletedNormally(cf3, 1);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
        cf3 = cf1.acceptEither(cf2, x -> {
            check(x == 1 || x == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.acceptEitherAsync(cf2, x -> {
            check(x == 1 || x == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            check(x == 1 || x == 2);
            atomicInt.incrementAndGet();
        }, executor);
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            check(x == 2);
        }, executor);
        try {
            check(cf3.join() == null);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            check(x == 1);
        });
        try {
            check(cf3.join() == null);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            fail();
        });
        checkCompletedExceptionally(cf3);
        check(cf1.isDone() || cf2.isDone());
        final Phaser cf3Done = new Phaser(2);
        cf1 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 1;
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.acceptEither(cf2, x -> {
            check(x == 2);
        });
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf2, 2);
        check(!cf1.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf3, null);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 2;
        });
        cf3 = cf1.acceptEitherAsync(cf2, x -> {
            check(x == 1);
        });
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf1, 1);
        check(!cf2.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf2, 2);
        checkCompletedNormally(cf3, null);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Void> cf1 = runAsync(() -> {
        });
        CompletableFuture<Void> cf2 = runAsync(() -> {
        });
        cf3 = cf1.runAfterEither(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> {
        });
        cf3 = cf1.runAfterEitherAsync(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> {
        });
        cf3 = cf2.runAfterEitherAsync(cf1, () -> atomicInt.incrementAndGet(), executor);
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = runAsync(() -> {
        });
        cf3 = cf2.runAfterEither(cf1, () -> atomicInt.incrementAndGet());
        try {
            check(cf3.join() == null);
            check(atomicInt.get() == (before + 1));
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.runAfterEitherAsync(cf2, () -> atomicInt.incrementAndGet());
        try {
            check(cf3.join() == null);
            check(atomicInt.get() == (before + 1));
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        before = atomicInt.get();
        cf1 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf2.runAfterEitherAsync(cf1, () -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf3);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == before);
        final Phaser cf3Done = new Phaser(2);
        before = atomicInt.get();
        cf1 = runAsync(() -> cf3Done.arriveAndAwaitAdvance());
        cf2 = runAsync(() -> {
        });
        cf3 = cf1.runAfterEither(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf2, null);
        check(!cf1.isDone());
        check(atomicInt.get() == (before + 1));
        cf3Done.arrive();
        checkCompletedNormally(cf1, null);
        checkCompletedNormally(cf3, null);
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> cf3Done.arriveAndAwaitAdvance());
        cf3 = cf1.runAfterEitherAsync(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf1, null);
        check(!cf2.isDone());
        check(atomicInt.get() == (before + 1));
        cf3Done.arrive();
        checkCompletedNormally(cf2, null);
        checkCompletedNormally(cf3, null);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenCompose(x -> {
            check(x == 1);
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenComposeAsync(x -> {
            check(x == 1);
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenComposeAsync(x -> {
            check(x == 1);
            return CompletableFuture.completedFuture(2);
        }, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        int before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenCompose(x -> {
            atomicInt.incrementAndGet();
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenComposeAsync(x -> {
            atomicInt.incrementAndGet();
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenComposeAsync(x -> {
            throw new RuntimeException();
        }, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedExceptionally(cf2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Object> cf3;
        for (int k = 0; k < 10; k++) {
            CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
            CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
            cf3 = CompletableFuture.anyOf(cf1, cf2);
            checkCompletedNormally(cf3, new Object[] { 1, 2 });
            check(cf1.isDone() || cf2.isDone());
        }
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<?> cf3;
        for (int k = 0; k < 10; k++) {
            CompletableFuture<Integer>[] cfs = (CompletableFuture<Integer>[]) Array.newInstance(CompletableFuture.class, 10);
            for (int j = 0; j < 10; j++) {
                final int v = j;
                cfs[j] = supplyAsync(() -> v);
            }
            cf3 = CompletableFuture.allOf(cfs);
            for (int j = 0; j < 10; j++) checkCompletedNormally(cfs[j], j);
            checkCompletedNormally(cf3, null);
        }
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.exceptionally(t -> {
            fail("function should never be called");
            return 2;
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        final RuntimeException t = new RuntimeException();
        cf1 = supplyAsync(() -> {
            throw t;
        });
        cf2 = cf1.exceptionally(x -> {
            check(x.getCause() == t);
            return 2;
        });
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.handle((x, t) -> x + 1);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        final RuntimeException ex = new RuntimeException();
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.handle((x, t) -> {
            check(t.getCause() == ex);
            return 2;
        });
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.handleAsync((x, t) -> x + 1);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.handleAsync((x, t) -> {
            check(t.getCause() == ex);
            return 2;
        });
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        AtomicInteger count = new AtomicInteger();
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.whenComplete((x, t) -> count.getAndIncrement());
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        check(count.get() == 1, "action count should be incremented");
        final RuntimeException ex = new RuntimeException();
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.whenComplete((x, t) -> count.getAndIncrement());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(count.get() == 2, "action count should be incremented");
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.whenCompleteAsync((x, t) -> count.getAndIncrement());
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        check(count.get() == 3, "action count should be incremented");
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.whenCompleteAsync((x, t) -> count.getAndIncrement());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(count.get() == 4, "action count should be incremented");
    } catch (Throwable t) {
        unexpected(t);
    }
}
Also used : ForkJoinPool.commonPool(java8.util.concurrent.ForkJoinPool.commonPool) CompletableFuture.supplyAsync(java8.util.concurrent.CompletableFuture.supplyAsync) Array(java.lang.reflect.Array) CancellationException(java.util.concurrent.CancellationException) Test(org.testng.annotations.Test) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) Executors(java.util.concurrent.Executors) ExecutionException(java.util.concurrent.ExecutionException) Phaser(java8.util.concurrent.Phaser) Utils(jdk.testlibrary.Utils) CompletableFuture(java8.util.concurrent.CompletableFuture) CompletableFuture.runAsync(java8.util.concurrent.CompletableFuture.runAsync) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletionException(java8.util.concurrent.CompletionException) SECONDS(java.util.concurrent.TimeUnit.SECONDS) ExecutorService(java.util.concurrent.ExecutorService) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletionException(java8.util.concurrent.CompletionException) Phaser(java8.util.concurrent.Phaser)

Example 4 with CompletableFuture.completedFuture

use of java8.util.concurrent.CompletableFuture.completedFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testRejectingExecutorNeverInvoked.

/**
 * Test submissions to an executor that rejects all tasks, but
 * should never be invoked because the dependent future is
 * explicitly completed.
 */
public void testRejectingExecutorNeverInvoked() {
    final CountingRejectingExecutor e = new CountingRejectingExecutor();
    for (Integer v : new Integer[] { 1, null }) {
        final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
        // List<CompletableFuture<?>> futures = new ArrayList<>();
        List<CompletableFuture<Integer>> srcs = new ArrayList<>();
        srcs.add(complete);
        srcs.add(incomplete);
        List<CompletableFuture<?>> fs = new ArrayList<>();
        fs.add(incomplete.thenRunAsync(() -> {
        }, e));
        fs.add(incomplete.thenAcceptAsync(z -> {
        }, e));
        fs.add(incomplete.thenApplyAsync(z -> z, e));
        fs.add(incomplete.thenCombineAsync(incomplete, (x, y) -> x, e));
        fs.add(incomplete.thenAcceptBothAsync(incomplete, (x, y) -> {
        }, e));
        fs.add(incomplete.runAfterBothAsync(incomplete, () -> {
        }, e));
        fs.add(incomplete.applyToEitherAsync(incomplete, z -> z, e));
        fs.add(incomplete.acceptEitherAsync(incomplete, z -> {
        }, e));
        fs.add(incomplete.runAfterEitherAsync(incomplete, () -> {
        }, e));
        fs.add(incomplete.thenComposeAsync(z -> null, e));
        fs.add(incomplete.whenCompleteAsync((z, t) -> {
        }, e));
        fs.add(incomplete.handleAsync((z, t) -> null, e));
        fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e));
        fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e));
        fs.add(complete.thenAcceptBothAsync(incomplete, (x, y) -> {
        }, e));
        fs.add(incomplete.thenAcceptBothAsync(complete, (x, y) -> {
        }, e));
        fs.add(complete.runAfterBothAsync(incomplete, () -> {
        }, e));
        fs.add(incomplete.runAfterBothAsync(complete, () -> {
        }, e));
        for (CompletableFuture<?> future : fs) checkIncomplete(future);
        for (CompletableFuture<?> future : fs) future.complete(null);
        incomplete.complete(v);
        for (CompletableFuture<?> future : fs) checkCompletedNormally(future, null);
        assertEquals(0, e.count.get());
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Arrays(java.util.Arrays) Test(junit.framework.Test) TimeoutException(java.util.concurrent.TimeoutException) Callable(java.util.concurrent.Callable) CompletableFuture.completedFuture(java8.util.concurrent.CompletableFuture.completedFuture) Predicate(java8.util.function.Predicate) AtomicReference(java.util.concurrent.atomic.AtomicReference) CompletableFuture.failedFuture(java8.util.concurrent.CompletableFuture.failedFuture) Function(java8.util.function.Function) ArrayList(java.util.ArrayList) TestSuite(junit.framework.TestSuite) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) BiFunction(java8.util.function.BiFunction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Consumer(java8.util.function.Consumer) ForkJoinPool(java8.util.concurrent.ForkJoinPool) Method(java.lang.reflect.Method) CompletionStage(java8.util.concurrent.CompletionStage) Objects(java8.util.Objects) CancellationException(java.util.concurrent.CancellationException) Executor(java.util.concurrent.Executor) ForkJoinTask(java8.util.concurrent.ForkJoinTask) Set(java.util.Set) Collectors(java8.util.stream.Collectors) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) StreamSupport(java8.util.stream.StreamSupport) Supplier(java8.util.function.Supplier) ExecutionException(java.util.concurrent.ExecutionException) List(java.util.List) CompletableFuture(java8.util.concurrent.CompletableFuture) BiConsumer(java8.util.function.BiConsumer) RefStreams(java8.util.stream.RefStreams) Modifier(java.lang.reflect.Modifier) CompletionException(java8.util.concurrent.CompletionException) SECONDS(java.util.concurrent.TimeUnit.SECONDS) CompletableFuture(java8.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList)

Aggregations

AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 CompletableFuture (java8.util.concurrent.CompletableFuture)4 CancellationException (java.util.concurrent.CancellationException)3 ExecutionException (java.util.concurrent.ExecutionException)3 MILLISECONDS (java.util.concurrent.TimeUnit.MILLISECONDS)3 SECONDS (java.util.concurrent.TimeUnit.SECONDS)3 CompletionException (java8.util.concurrent.CompletionException)3 Method (java.lang.reflect.Method)2 Modifier (java.lang.reflect.Modifier)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 List (java.util.List)2 Set (java.util.Set)2 Callable (java.util.concurrent.Callable)2 Executor (java.util.concurrent.Executor)2 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 Objects (java8.util.Objects)2 CompletableFuture.completedFuture (java8.util.concurrent.CompletableFuture.completedFuture)2