Java CompletableFuture可继续执行多个并行任务的单个任务
我有以下代码:Java CompletableFuture可继续执行多个并行任务的单个任务,java,multithreading,java-8,completable-future,Java,Multithreading,Java 8,Completable Future,我有以下代码: return CompletableFuture.supplyAsync(() -> { return foo; // some custom object }) .thenAccept(foo -> { // ??? need to spawn N async parallel jobs that works on 'foo' }); 英文:第一个任务异步创建foo对象;然后我需要在上面运行N个并行进程 那么,有没有更好的方法: ... Comp
return CompletableFuture.supplyAsync(() -> {
return foo; // some custom object
})
.thenAccept(foo -> {
// ??? need to spawn N async parallel jobs that works on 'foo'
});
英文:第一个任务异步创建foo
对象;然后我需要在上面运行N个并行进程
那么,有没有更好的方法:
...
CompletableFuture[] parallel = new CompletableFuture[N];
for (int i = 0; i < N; i++) {
parallel[i] = CompletableFuture.runAsync(() -> {
work(foo);
});
}
CompletableFuture.allOf(parallel).join();
...
。。。
CompletableFuture[]并行=新的CompletableFuture[N];
对于(int i=0;i{
工作(foo);
});
}
CompletableFuture.allOf(parallel.join();
...
我不喜欢这样,因为一个线程在等待N个作业完成时被锁定。因为
CompletableFuture。allOf
已经返回另一个CompletableFuture
a您只需执行另一个。然后接受它并从回调中的parallel
中的CFs提取返回值,通过这种方式,您可以避免调用join
您可以在特定的先决条件作业上链接任意多个独立作业,例如
CompletableFuture<Foo> base=CompletableFuture.supplyAsync(() -> new Foo());
Collections.nCopies(N, base).forEach(f -> f.thenAcceptAsync(foo -> work(foo)));
现在,您可以使用all
检查所有作业的完成情况或链附加操作。为什么有这行CompletableFuture.allOf(parallel.join()代码>当您不想等待完成时?没有人要求您等待…我当时是瞎子。或者我可以在外部创建数组,然后在循环中使用然后AcceptsSync
创建并行任务。“如果工作是i/O绑定的,那么,您希望有更多的并行线程”——这是为什么?也许您缺少了同步I/O绑定,或者更好的是,“如果工作阻塞”。@acelent:是一个通用术语,用于所有类型的潜在阻塞任务,而不是CPU绑定的任务。CompletableFuture
使用的默认执行器配置为适用于CPU限制的任务,这是所有需要知道的……”是一个通用术语,用于所有类型的潜在阻塞任务,与CPU限制的任务相反。”--那么,请允许我不同意。我将CompletableFuture
与AsynchronousSocketChannel
采用CompletionHandler
的方法进行了桥接,而且它肯定不需要比内核更多的线程池线程,因为它不会阻塞。然而,使用任何类型的阻塞代码,无论是I/O、等待还是休眠,都可能需要更多的线程池线程来拥有与内核一样多的可运行线程。等待或睡眠中没有I/O。@acelent:不要试图重新定义已建立的术语。“I/O绑定”使用“I/O”,即CPU本身无法处理的所有事情。如果您将请求推送到一个无争用队列,则它不受I/O限制,即使队列的使用者被称为AsynchronousSocketChannel
。好吧,如果你让异步socketchannel
的CompletionHandler
完成CompletableFuture
,你实际上是在使用一个与异步socketchannel
不同的执行器,“不要试图重新定义已建立的术语。”——不管怎样。“好吧,如果您让异步socketchannel
的完成处理程序
完成可完成的未来
,那么您实际上使用了一个与异步socketchannel
不同的执行器”——消费者要么接受此方法,要么使用*Async
方法。但这有点离题了,我只是把它作为实际“I/O”的一个例子,例如,产生/休眠或等待锁、互斥、信号量等不是“I/O”。我的意思是,甚至维基百科的文章也不支持你的定义。让我们同意不同意吧。
CompletableFuture<Foo> base=CompletableFuture.supplyAsync(() -> new Foo());
CompletableFuture<Void> all = CompletableFuture.allOf(
Collections.nCopies(N, base).stream()
.map(f -> f.thenAcceptAsync(foo -> work(foo)))
.toArray(CompletableFuture<?>[]::new));