Search in sources :

Example 26 with Phaser

use of java8.util.concurrent.Phaser 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 27 with Phaser

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

the class DoubleAdderDemo method syncTest.

static void syncTest(int nthreads, int incs) {
    System.out.print("Synchronized ");
    Phaser phaser = new Phaser(nthreads + 1);
    SynchronizedDoubleAdder a = new SynchronizedDoubleAdder();
    for (int i = 0; i < nthreads; ++i) pool.execute(new SyncTask(a, phaser, incs));
    report(nthreads, incs, timeTasks(phaser), a.sum());
}
Also used : Phaser(java8.util.concurrent.Phaser)

Example 28 with Phaser

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

the class DoubleAdderDemo method adderTest.

static void adderTest(int nthreads, int incs) {
    System.out.print("DoubleAdder  ");
    Phaser phaser = new Phaser(nthreads + 1);
    DoubleAdder a = new DoubleAdder();
    for (int i = 0; i < nthreads; ++i) pool.execute(new AdderTask(a, phaser, incs));
    report(nthreads, incs, timeTasks(phaser), a.sum());
}
Also used : DoubleAdder(java8.util.concurrent.atomic.DoubleAdder) Phaser(java8.util.concurrent.Phaser)

Example 29 with Phaser

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

the class LongAdderDemo method casTest.

static void casTest(int nthreads, int incs) {
    System.out.print("AtomicLong ");
    Phaser phaser = new Phaser(nthreads + 1);
    AtomicLong a = new AtomicLong();
    for (int i = 0; i < nthreads; ++i) pool.execute(new CasTask(a, phaser, incs));
    report(nthreads, incs, timeTasks(phaser), a.get());
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) Phaser(java8.util.concurrent.Phaser)

Example 30 with Phaser

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

the class Collection8Test method testDetectRaces.

/**
 * Motley crew of threads concurrently randomly hammer the collection.
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test(dataProvider = "Source")
public void testDetectRaces(String description, Supplier<CollectionImplementation> sci) throws Throwable {
    CollectionImplementation impl = sci.get();
    if (!impl.isConcurrent())
        return;
    if (HAS_JAVA8_SPLITERATOR_BUG && LinkedBlockingDeque.class.equals(impl.klazz())) {
        // https://bugs.openjdk.java.net/browse/JDK-8169739
        return;
    }
    if (CopyOnWriteArraySet.class.equals(impl.klazz())) {
        return;
    }
    final ThreadLocalRandom rnd = ThreadLocalRandom.current();
    final Collection c = impl.emptyCollection();
    final long testDurationMillis = expensiveTests ? LONG_DELAY_MS : timeoutMillis();
    final AtomicBoolean done = new AtomicBoolean(false);
    final Object one = impl.makeElement(1);
    final Object two = impl.makeElement(2);
    final Consumer checkSanity = x -> assertTrue(x == one || x == two);
    final Consumer<Object[]> checkArraySanity = array -> {
        // assertTrue(array.length <= 2); // duplicates are permitted
        for (Object x : array) assertTrue(x == one || x == two);
    };
    final Object[] emptyArray = (Object[]) java.lang.reflect.Array.newInstance(one.getClass(), 0);
    final List<Future<?>> futures;
    // register this thread
    final Phaser threadsStarted = new Phaser(1);
    final Runnable[] frobbers = { () -> Iterables.forEach(c, checkSanity), () -> StreamSupport.stream(c).forEach(checkSanity), () -> StreamSupport.parallelStream(c).forEach(checkSanity), () -> Spliterators.spliterator(c).trySplit(), () -> {
        Spliterator<?> s = Spliterators.spliterator(c);
        s.tryAdvance(checkSanity);
        s.trySplit();
    }, () -> {
        Spliterator<?> s = Spliterators.spliterator(c);
        do {
        } while (s.tryAdvance(checkSanity));
    }, () -> {
        for (Object x : c) checkSanity.accept(x);
    }, () -> checkArraySanity.accept(c.toArray()), () -> checkArraySanity.accept(c.toArray(emptyArray)), () -> {
        Object[] a = new Object[5];
        Object three = impl.makeElement(3);
        Arrays.fill(a, 0, a.length, three);
        Object[] x = c.toArray(a);
        if (x == a)
            for (int i = 0; i < a.length && a[i] != null; i++) checkSanity.accept(a[i]);
        else
            // A careful reading of the spec does not support:
            // for (i++; i < a.length; i++) assertSame(three, a[i]);
            checkArraySanity.accept(x);
    }, adderRemover(c, one), adderRemover(c, two) };
    final List<Runnable> tasks = J8Arrays.stream(frobbers).filter(// random subset
    task -> rnd.nextBoolean()).map(task -> (Runnable) () -> {
        threadsStarted.arriveAndAwaitAdvance();
        while (!done.get()) task.run();
    }).collect(Collectors.<Runnable>toList());
    final ExecutorService pool = Executors.newCachedThreadPool();
    PoolCleaner cleaner = null;
    try {
        cleaner = cleaner(pool, done);
        threadsStarted.bulkRegister(tasks.size());
        futures = StreamSupport.stream(tasks).map(pool::submit).collect(Collectors.toList());
        threadsStarted.arriveAndDeregister();
        Thread.sleep(testDurationMillis);
    } finally {
        if (cleaner != null) {
            cleaner.close();
        }
    }
    for (Future<?> future : futures) assertNull(future.get(0L, MILLISECONDS));
}
Also used : Arrays(java.util.Arrays) DataProvider(org.testng.annotations.DataProvider) PriorityQueue(java.util.PriorityQueue) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.testng.annotations.Test) Iterables(java8.lang.Iterables) Deque(java.util.Deque) Predicate(java8.util.function.Predicate) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) PriorityBlockingQueue(java.util.concurrent.PriorityBlockingQueue) HashSet(java.util.HashSet) Phaser(java8.util.concurrent.Phaser) Iterators(java8.util.Iterators) Future(java.util.concurrent.Future) J8Arrays(java8.util.J8Arrays) Vector(java.util.Vector) Consumer(java8.util.function.Consumer) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) ExecutorService(java.util.concurrent.ExecutorService) Iterator(java.util.Iterator) BlockingDeque(java.util.concurrent.BlockingDeque) Collection(java.util.Collection) Spliterator(java8.util.Spliterator) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) Collectors(java8.util.stream.Collectors) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) Spliterators(java8.util.Spliterators) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) StreamSupport(java8.util.stream.StreamSupport) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Executors(java.util.concurrent.Executors) Supplier(java8.util.function.Supplier) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) ThreadLocalRandom(java8.util.concurrent.ThreadLocalRandom) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) HOURS(java.util.concurrent.TimeUnit.HOURS) Queue(java.util.Queue) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) ConcurrentModificationException(java.util.ConcurrentModificationException) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Consumer(java8.util.function.Consumer) ExecutorService(java.util.concurrent.ExecutorService) ThreadLocalRandom(java8.util.concurrent.ThreadLocalRandom) Collection(java.util.Collection) Future(java.util.concurrent.Future) Phaser(java8.util.concurrent.Phaser) Test(org.testng.annotations.Test)

Aggregations

Phaser (java8.util.concurrent.Phaser)51 CountDownLatch (java.util.concurrent.CountDownLatch)9 ArrayList (java.util.ArrayList)8 ExecutorService (java.util.concurrent.ExecutorService)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 LinkedList (java.util.LinkedList)2 Executors (java.util.concurrent.Executors)2 MILLISECONDS (java.util.concurrent.TimeUnit.MILLISECONDS)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 Test (org.testng.annotations.Test)2 Array (java.lang.reflect.Array)1 ArrayDeque (java.util.ArrayDeque)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 ConcurrentModificationException (java.util.ConcurrentModificationException)1 Deque (java.util.Deque)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 List (java.util.List)1