4

我已经阅读了很多关于 CompletableFutures 的内容,他们关注 CompletableFuture 无法像 Future 那样访问底层计算代码这一事实。那么,如何从与 completableFuture 关联的任何任务中发出完成()或取消()(或检查 isCancelled(),如果您想从外部中断计算)?

编辑:让我感到困惑的一件事是,CF 被用于替代替代品,因为它的可组合性或手动可设置性,在我看来,提供的实现非常正交,例如:

CompletableFuture.runAsync(() -> { 
                              if(myCondition) CF_REF?.complete();
                              else            CF_REF?.exceptionally();
                           }).thenApply(() -> {
                                        if (myOtherCondition) CF_REF_2?.complete();
 (...)

以不是“可完成”+“可组合”的方式设计它有什么意义?

我想找到一种方法来使用它们,就好像 CF 使用类似于假设的 CompletableCallable 的接口作为输入,但不知道如何。Function<CompletableFuture,T>代替 Callables/Runnables 之类的东西,所以我们可以将其用作:

CompletableFuture CF_REF_BIS = CompletableFuture.runAsync((CF_REF) -> { 
                                  if(myCondition) CF_REF.complete();
                                  else CF_REF.exceptionally();
                               });

CF_REF_BIS.thenApply(...)

当要计算代码时,内部执行机制将返回 CF_REF_BIS 引用,因为在未来的计算中实际作为 CF_REF 传递,而无需跨范围访问它。

这意味着我们可以简单地通过创建 new CompeltableCallable() 然后在任何线程可以访问 CompletableFuture 信号量的任何地方提交 n 次来重用去匿名化计算代码

例如:

CompletableFuture CF_REF = CompletableFuture.runAsync(myCompletableCallable)
             .thenApply(myCompletableCallable) //again
             .thenApply(anotherCompletableCallable); 

有没有办法满足这种需求?我是不是忘记了什么?我的方法有什么根本的不一致吗?Java CompletableFuture 是否还在半途而废的便捷设计中?

4

1 回答 1

2

看一下javadoc:

CompletableFuture#complete()

如果尚未完成,则将由get()和相关方法返回的值设置为给定值。

CompletableFuture#cancel()

如果尚未完成,请CompletableFuture使用 CancellationException. CompletableFuture尚未完成的 Dependent也会异常完成,CompletionException由 this 引起CancellationException

[...]

参数:

mayInterruptIfRunning - 这个值在这个实现中没有影响,因为中断不用于控制处理。

CompletableFuture对象与可能对它们有可访问引用的任何线程完全无关。换句话说,这些对象并不意味着向线程发出信号。这种类型的未来基本上是结果的持有者,可以选择注册听众。

whenXyz和的所有行为都在对象thenAbc中注册。CompletableFuture该行为何时执行取决于许多事情:未来哪个线程完成(成功或异常),是否向方法注册了延续,等等。这在javadoc*Async中列出。


例如,您创建一个CompletableFuture并将其交给一些线程。据推测,这些线程之一将complete它。这对其他线程没有影响。他们仍然继续做他们正在做或试图做的事情。

public static void main(String[] args) throws Exception {
    CompletableFuture<String> promise = new CompletableFuture<>();
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    Runnable action = () -> {
        if (promise.complete("done")) {
            System.out.println("completed by " + Thread.currentThread());
        } else {
            System.out.println("somebody got there first");
        }
    };
    executorService.submit(action);
    executorService.submit(action);
    executorService.submit(action);

    executorService.shutdown();
    executorService.awaitTermination(100, TimeUnit.MILLISECONDS);
    System.out.println(promise.get());
}
于 2015-11-30T02:38:51.397 回答