简体   繁体   English

Java等待所有线程完成

[英]Java Waiting for all threads to complete

Edit: My question is different, it has no relevance to the linked question. 编辑:我的问题是不同的,它与链接的问题无关。

I've following code with completion handler. 我正在用完成处理程序跟踪代码。

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();

Basically I'm looking for completion handler for variable number of tasks, or is there another approach? 基本上,我正在寻找可变数量任务的完成处理程序,还是有另一种方法?

I'm inspired from this answer but seems it's part of some library while I'm looking for a native solution. 我从这个答案中得到启发,但是当我在寻找本机解决方案时,它似乎是某些库的一部分。

Completable Future ??? 可完成的未来

Here's my attempt with completable futures with the result handler at the end. 这是我尝试使用最终结果处理程序完成的期货。

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";
}

Assuming that your method result() returns a value that you want to retrieve, ie is declared like Type result() , you can use 假设您的方法result()返回要检索的值,即像Type result()那样声明,则可以使用

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

Each runAsync creates an individual asynchronous CompletableFuture that will be completed once the Runnable has been executed. 每个runAsync创建一个单独的异步CompletableFuture ,一旦执行了Runnable ,该异步CompletableFuture将完成。 It's the same as supplyAsync , except that it doesn't return a result. 除了不返回结果外,它与supplyAsync相同。

allOf create a CompletableFuture that will be completed, once all specified futures are completed, hence, any chained dependent action will only run after all futures have been completed. allOf创建一个CompletableFuture ,一旦所有指定的期货都完成,该CompletableFuture将完成,因此,任何相关的连锁操作都将在所有期货都已完成之后运行。 By using thenApply we create a dependent future that will be completed with the return value of result() . 通过使用thenApply我们创建了一个依存的thenApply ,它将以result()的返回值完成。

If result() is not intended to return a value, but just an action that should run after all other actions have been completed, you can use 如果result()并非要返回值,而只是要在所有其他动作完成后才运行的动作,则可以使用

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

instead. 代替。

One easy approach is to submit your Runnable(s) to an ExecutorService, then call shutdown , then call awaitTermination : 一种简单的方法是将您的Runnable提交给ExecutorService,然后调用shutdown ,然后调用awaitTermination

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

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

No need to use CompletableFuture. 无需使用CompletableFuture。

Save the links to the threads you've created, and call join() 保存到您创建的线程的链接,然后调用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

Depending on how much control you want you could use a ThreadPoolExecutor: 根据您想要多少控制权,您可以使用ThreadPoolExecutor:

tpe.execute(Runnable); tpe.execute(Runnable);

Wait for the active count == 0; 等待有效计数== 0;

then shutdown the executor. 然后关闭执行器。

Or keep the threads in a structure. 或者将线程保持在一个结构中。

Wait for an specific TTL then interrupt them if the state is RUNNABLE 等待特定的TTL,然后在状态为RUNNABLE时中断它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM