0

我有 1000 个大文件要按如下所述顺序处理:

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

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

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

4

1 回答 1

1

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

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
                ...
            }
        );
}
于 2020-09-06T21:08:03.127 回答