completionservice与completablefuture

bvhaajcl  于 2021-07-04  发布在  Java
关注(0)|答案(1)|浏览(587)

我有1000个大文件要处理,顺序如下:
首先,这些文件需要复制到不同的目录并行,我计划使用 ExecutorService 用10个线程来实现。
一旦任何文件被复制到另一个位置(#1),我会将该文件提交给 ExecutorService 有10根线。
最后,还需要对这些文件并行执行另一个操作,例如#2从#1获取输入,#3从#2获取输入。
现在,我可以用 CompletionService 在这里,我可以按完成的顺序处理从#1到#2和#2到#3的线程结果。 CompletableFuture 说我们可以将异步任务链接在一起,这听起来像是我在本例中可以使用的东西。
我不确定我是否应该用 CompletableFuture (因为它相对较新,应该更好)或者 CompletionService 足够吗?在这种情况下,我为什么要选择一个而不是另一个呢?

eqoofvh9

eqoofvh91#

如果你两种方法都试过,然后选择一种你更习惯的方法,那可能是最好的。虽然听起来像 CompletableFuture s更适合此任务,因为它们使链接处理步骤/阶段非常容易。例如,在您的示例中,代码可能如下所示:

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

public CompletableFuture<MyResult> process(Path file) {
    return CompletableFuture
        .supplyAsync(
            () -> {
                // 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 -> {
                // 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 -> {
                // Process the previous result
                ...
            }
        );
}

相关问题