【问题标题】:CompletionService vs CompletableFutureCompletionService 与 CompletableFuture
【发布时间】:2020-09-06 08:15:07
【问题描述】:

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

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

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

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

【问题讨论】:

  • “#2 从 #1 获取输入,#3 从 #2 获取输入”是什么意思?
  • @AlexeiKaigorodov - 我的意思是,一旦第 1 步任务完成,这些任务的结果就会被第 2 步消耗掉。
  • 1,2等步骤是什么?

标签: java multithreading java.util.concurrent completable-future completion-service


【解决方案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
                ...
            }
        );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 2016-06-08
    • 2018-01-11
    • 2018-12-11
    • 2016-03-11
    • 1970-01-01
    • 2017-12-07
    相关资源
    最近更新 更多