Java等待所有线程完成

时间:2017-02-16 19:17:32

标签: java multithreading java-8 completable-future futuretask

编辑:我的问题不同,它与链接的问题无关。

我使用完成处理程序跟踪代码。

FutureTask<Void> futureTask = new FutureTask<Void>(() -> {
    System.out.println("callback");
    return null;
});

Runnable task = () -> {
    for(int i=0; i<5; i++) {
        System.out.println(Thread.currentThread().getName() + " " + i);
    }
    futureTask.run();
};

new Thread(task).start();
new Thread(task).start();

基本上我正在为可变数量的任务寻找完成处理程序,还是有另一种方法?

我从这个answer中受到启发,但在我寻找本机解决方案的时候,它似乎是某个库的一部分。

Completable Future ...

这是我在最后使用结果处理程序的可完成期货的尝试。

public void test() {
    CompletableFuture
            .supplyAsync(() -> method1())
            .supplyAsync(() -> method2())
            .supplyAsync(() -> result());
}

public String method1() {
    System.out.println("calling 1");
    return "method1";
}

public String method2() {
    System.out.println("calling 2");
    return "method2";
}

public String result() {
    System.out.println("result");
    return "result";
}

4 个答案:

答案 0 :(得分:2)

假设您的方法result()返回您要检索的值,即声明为Type result(),您可以使用

CompletableFuture<Type> f = CompletableFuture.allOf(
    CompletableFuture.runAsync(() -> method1()),
    CompletableFuture.runAsync(() -> method2())
).thenApply(_void -> result());

每个runAsync创建一个单独的异步CompletableFuture,一旦执行Runnable,就会完成。它与supplyAsync相同,只是它不返回结果。

allOf创建一个CompletableFuture,一旦完成所有指定的期货,就会完成,因此,任何链接的相关操作只会在所有期货完成后运行。通过使用thenApply,我们创建了一个将使用result()的返回值完成的从属未来。

如果result()无意返回值,而只是在所有其他操作完成后应该运行的操作,则可以使用

CompletableFuture.allOf(
    CompletableFuture.runAsync(() -> method1()),
    CompletableFuture.runAsync(() -> method2())
).thenRun(() -> result());

代替。

答案 1 :(得分:1)

一种简单的方法是将您的Runnable提交给ExecutorService,然后拨打shutdown,然后拨打awaitTermination

ExecutorService executor = Executors.newWorkStealingPool();
executor.submit(task);
executor.submit(task);

executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

无需使用CompletableFuture。

答案 2 :(得分:0)

保存指向您已创建的主题的链接,然后致电join()

Thread a = new Thread(task);
Thread b = new Thread(task);
a.start();
b.start();

a.join();
b.join();
//guaranteed that both threads have completed here

答案 3 :(得分:0)

根据您想要的控制程度,您可以使用ThreadPoolExecutor:

tpe.execute(可运行);

等待活动计数== 0;

然后关闭执行程序。

或者将线程保留在结构中。

等待特定TTL,然后在状态为RUNNABLE

时中断它们