【问题标题】:How do I proceed with CompletableFuture without waiting for output如何在不等待输出的情况下继续 CompletableFuture
【发布时间】:2016-09-24 08:24:27
【问题描述】:

我遇到了需要使用CompletableFuture 实现递归的情况。每当CompletableFutures 中的任何一个返回任何结果时,我都想调用recursionFuture(ex),但我不确定如何实现它。在当前情况下,recursionFuture(ex) 仅在 future1future2 都返回输出时调用,然后如果条件正在检查。任何帮助将不胜感激。

public static void recursionFuture(ExecutorService ex) 
    {
        try
        {
            CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex);  
            CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex);

            if (future1.get() != null | future2.get() != null)
            { 
                System.out.println("Future1: " + future1.get() + " Future2: " + future2.get());
                recursionFuture(ex);
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

【问题讨论】:

    标签: java multithreading threadpool executorservice completable-future


    【解决方案1】:

    您可以将anyOf()thenRun() 结合使用来实现此目的。只是不要在两个期货上都调用get(),因为它会让你的程序等待完成。您可以在调用get() 之前使用isDone() 检查未来是否完成。

    CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex);  
    CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex);
    
    CompletableFuture.anyOf(future1, future2).thenRun(() -> {
        if (future1.isDone()) {
            System.out.println("Future 1: " + future1.get());
        }
        if (future2.isDone()) {
            System.out.println("Future 2: " + future2.get());
        }
        recursionFuture(ex);
    });
    

    anyOf() 将创建一个新的未来,该未来将在任何提供的未来完成后立即完成。 thenRun() 将在调用它的 future 完成后立即执行给定的 Runnable

    【讨论】:

    • 感谢 Andrew,这可行,但有一个小问题。由于递归,即使 executeTask() 没有返回任何东西并且无限期地继续,代码也会继续。是否可以检查futire1.get() != null 之类的future 的输出,然后调用递归,但是会发生前面所述的问题。请您在这里提供建议。
    • 好吧,我通过编辑以下代码来完成这项工作: CompletableFuture.anyOf(future1, future2).thenRunAsync(()-> { recursionFuture(ex); } , ex);
    【解决方案2】:

    如果你只使用两个 CompletableFuture,你也可以看看 runAfterEither / runAfterEitherAsync。还有一些版本允许访问返回的值,例如 acceptEither / acceptEitherAsync。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-07
      • 2012-01-30
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多