CompletionService与CompletableFuture

问题描述

我要处理1000个大文件,如下所述:

  1. 首先,这些文件需要并行复制到其他目录,我计划使用具有10个线程的ExecutorService来实现。
  2. 将任何文件复制到另一个位置(#1)后,我将将该文件提交给具有10个线程的ExecutorService进行进一步处理。
  3. 最后,还需要对这些文件并行执行另一个操作,例如#2从#1获取输入,#3从#2获取输入。

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

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

解决方法

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...