多线程 – 如何在与它们相关联的线程内完成或取消CompletableFutures的信号?

我一直在阅读很多有关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的接口作为输入,但不知道如何.类似函数< 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,而不需要在范围内访问它.

这意味着我们可以重复使用去匿名化计算代码
 只需创建新的CompeltableCallable(),然后在任何地方提交n次,任何线程都可以访问CompletableFuture信号量

例如:

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

有没有办法来满足这种需求?我忘记了什么吗?我的方法有任何根本的不一致吗? Java CompletableFuture仍处于中途方便的设计中吗?

最佳答案 看看javadoc:

CompletableFuture#complete()

If not already completed, sets the value returned by get() and related
methods to the given value.

CompletableFuture#cancel()

If not already completed, completes this CompletableFuture with a
CancellationException. Dependent CompletableFutures that have not
already completed will also complete exceptionally, with a
CompletionException caused by this CancellationException.

[…]

Parameters:

mayInterruptIfRunning – this value has no effect in this implementation because interrupts are not used to control processing.

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

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

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

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());
}
点赞