如果没有人持有对 CompletableFuture 的引用,它是否总是会在被垃圾收集之前完成?

问题描述 投票:0回答:1

Java 对象一旦无法访问就有资格进行垃圾回收,我的困惑是无法访问的 CompletableFutures 会发生什么,如下所示:

void someMethod(){
     methodThatProduceCompletableFuture()
          .thenAccept(s -> //produce some side effect);
}

对 someMethod 的调用可能会在 CompletableFuture 完成之前返回,因为没有人持有对 CompletableFuture 的引用,这个 CompletableFuture 会在完成之前被垃圾回收吗?

java garbage-collection future completable-future
1个回答
0
投票

你的问题的答案

你的问题的答案是这样的:“如果没有人持有对 CompletableFuture 的引用,那么它总是会在被垃圾收集之前完成吗?”是不,它永远不会完成。如果没有人持有对 CompletableFuture 的引用,那么某人就不可能在所述 future 上调用

complete()

您想要的问题的答案(大概)

不过,我认为这不是你问题的意图。让我猜一下预期的上下文并重新表述一下:

“如果我的代码没有显式引用 CompletableFuture,它会在垃圾收集之前完成吗?”

答案是,视情况而定。让我们用你的例子。

void someMethod(){
     methodThatProduceCompletableFuture()
          .thenAccept(s -> //produce some side effect);
}

首先关注

methodThatProduceCompletableFuture()
,如果这个方法所做的只是创造一个空的未来——

CompletableFuture<Boolean> methodThatProduceCompletableFuture() {
    return new CompletableFuture<>();
}

那么这将在完成之前被垃圾收集。没有人拥有对返回的未来的引用。因此,它既符合垃圾收集的条件,又无法完成。 但是,如果你这样实现——

CompletableFuture<Boolean> methodThatProduceCompletableFuture() { return CompletableFuture.supplyAsync(() -> someJobThatReturnsBoolean()); }

这是一个不同的故事。它可能看起来与第一个实现类似,但这里的关键区别是这个实现将
产生一个引用未来的线程

。一旦该工作完成,它将在我们返回的未来上调用 complete()。这就是让未来保持活力的参考。

基本上就是这样。 

thenAccept()

一开始可能看起来有所不同,但随后您意识到

methodThatProduceCompletableFuture()
生成的 CompletableFuture 必须持有对此 future 的引用,以便它在第一个 future 完成时运行。那么,答案可以归结为
methodThatProduceCompletableFuture()
是否会生成一个具有对其引用并会完成的 CompletableFuture。
附录1

我有时会捏造“被引用”和“将完成”的用法,以避免事情过于复杂。有区别。如果一个对象被“引用”,它就不会被垃圾收集。但仅仅因为它不会被垃圾收集,并不意味着它“将会完成”。这取决于传递到 CompletableFuture 中的操作。

正如一开始提到的,如果一个对象没有被引用,它就不可能完成,因为无法访问

complete()

函数。

附录2

从某种程度上来说,这个问题的答案是“别想”。如果您的 CompletableFuture 被编写为使其能够完成,那么这意味着某人在某个地方持有对您的未来的引用并将完成它。

即使在上面的

new CompletableFuture<>()

情况下,只要你在某个地方通过了那个未来并且有人计划完成它,那么你的操作链就是安全的。

    

© www.soinside.com 2019 - 2024. All rights reserved.