CompletionService与CompletableFuture

huangapple go评论72阅读模式
英文:

CompletionService vs CompletableFuture

问题

以下是翻译好的部分:

我有1000个大文件需要按照下面提到的顺序进行处理:

  1. 首先,这些文件需要并行地复制到另一个目录中,我计划使用ExecutorService和10个线程来实现。
  2. 一旦任何文件被复制到另一个位置(#1),我将提交该文件以进一步在ExecutorService中使用10个线程进行处理。
  3. 最后,需要对这些文件执行另一个并行操作,就像#2从#1获取输入,#3从#2获取输入。

现在,我可以在这里使用CompletionService,这样我就可以按照它们完成的顺序处理从#1到#2的线程结果,以及从#2到#3的线程结果。CompletableFuture说我们可以将异步任务链接在一起,这听起来就像是我可以在这种情况下使用的东西。

我不确定是否应该使用CompletableFuture来实现我的解决方案(因为它相对较新,应该更好),还是CompletionService已经足够?在这种情况下,我为什么要选择其中之一?

英文:

I have 1000 big files to be processed in order as mentioned below:

  1. First those files needs to be copied to a different directory in parallel, I am planning to use ExecutorService with 10 threads to achieve it.
  2. As soon as any file is copied to another location(#1), I will submit that file for further processing to ExecutorService with 10 threads.
  3. And finally, another action needs to be performed on these files in parallel, like #2 gets input from #1, #3 gets input from #2.

Now, I can use CompletionService here, so I can process the thread results from #1 to #2 and #2 to #3 in the order they are getting completed. CompletableFuture says we can chain asynchronous tasks together which sounds like something I can use in this case.

I am not sure if I should implement my solution with CompletableFuture (since it is relatively new and ought to be better) or if CompletionService is sufficient? And why should I chose one over another in this case?

答案1

得分: 1

这种情况下,尝试两种方法然后选择你更为舒适的一种可能是最好的。虽然听起来 CompletableFuture 更适合这个任务,因为它们能够很轻松地链式处理步骤/阶段。例如在你的情况下,代码可能如下所示:

ExecutorService copyingExecutor = ...
// 根据需求不太清楚,但假设你有一个专门的执行器
ExecutorService processingExecutor = ...

public CompletableFuture<MyResult> process(Path file) {
    return CompletableFuture
        .supplyAsync(
            () -> {
                // 获取文件应该被复制到的目标路径
                Path destination = ...
                try {
                    Files.copy(file, destination);
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
                return destination;
            },
            copyingExecutor
        )
        .thenApplyAsync(
            copiedFile -> {
                // 处理被复制的文件
                ...
            },
            processingExecutor
        )
        // 这个独立的阶段意义不大,所以除非你有另一个执行器用于此阶段,或者此阶段在代码中的不同位置应用,否则它可能应该与前一个阶段合并
        .thenApply(
            previousResult -> {
                // 处理前一个结果
                ...
            }
        );
}
英文:

It would probably be best if you tried both approaches and then choose the one you are more comfortable with. Though it sounds like CompletableFutures are better suited for this task because they make chaining processing steps / stages really easy. For example in your case the code could look like this:

ExecutorService copyingExecutor = ...
// Not clear from the requirements, but let&#39;s assume you have
// a separate executor for this
ExecutorService processingExecutor = ...

public CompletableFuture&lt;MyResult&gt; process(Path file) {
    return CompletableFuture
        .supplyAsync(
            () -&gt; {
                // Retrieve destination path where file should be copied to
                Path destination = ...
                try {
                    Files.copy(file, destination);
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
                return destination;
            },
            copyingExecutor
        )
        .thenApplyAsync(
            copiedFile -&gt; {
                // Process the copied file
                ...
            },
            processingExecutor
        )
        // This separate stage does not make much sense, so unless you have
        // yet another executor for this or this stage is applied at a different
        // location in your code, it should probably be merged with the
        // previous stage
        .thenApply(
            previousResult -&gt; {
                // Process the previous result
                ...
            }
        );
}

huangapple
  • 本文由 发表于 2020年9月6日 16:15:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63762096.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定