我一直在阅读很多有关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:
If not already completed, sets the value returned by
get()
and related
methods to the given value.
If not already completed, completes this
CompletableFuture
with a
CancellationException
. DependentCompletableFuture
s that have not
already completed will also complete exceptionally, with a
CompletionException
caused by thisCancellationException
.[…]
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());
}