Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java CompletableFuture可继续执行多个并行任务的单个任务_Java_Multithreading_Java 8_Completable Future - Fatal编程技术网

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