编辑:我的问题不同,它与链接的问题无关。
我使用完成处理程序跟踪代码。
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中受到启发,但在我寻找本机解决方案的时候,它似乎是某个库的一部分。
这是我在最后使用结果处理程序的可完成期货的尝试。
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";
}
答案 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
时中断它们