CompletableFuture和垃圾回收

7

我希望能够启动许多一次性的异步CompletableFutures,如下所示:

for (Job job : jobs) {
 CompletableFuture.supplyAsync(() -> job.process())
   .whenComplete(this::doSomething);
}

理想情况下,这些CompletableFuture在whenComplete完成后可以被垃圾回收。但是,如果我没有存储引用,它们会在此之前被回收吗?

1
在标记阶段,所有从Java线程、本地句柄和其他根源可达的对象都被标记为活动对象,以及从这些对象可达的对象等等。该过程识别并标记所有仍在使用的对象,其余对象可以视为垃圾。 - tsolakp
请注意,有一种特殊情况,即当main()返回时,它们不需要被完成:https://dev59.com/aLLma4cB1Zd3GeqPea3I - user202729
1个回答

12

虽然你没有显式地存储引用,但是 supplyAsync 在内部会这样做。该方法创建一个 CompletableFuture 并向 ForkJoinPool(如果你使用的是公共池)提交一个任务,该任务具有对该对象的引用。由 whenComplete 返回的 CompletableFuture 将成为第一个 CompletableFuture 的依赖项,因此也被引用。

所有这些对象将在 ForkJoinPool 执行 Supplier、标记第一个 CompletableFuture 为完成、触发第二个 CompletableFuture 和执行传递给 whenCompleteBiConsumer 后可供垃圾回收。

你是安全的。


我检查了supplyAsync的源代码,并确认提交给执行器的AsyncSupply<T>可运行对象持有对CompletableFuture的引用。 - kantianethics
2
简而言之,垃圾收集器不会改变程序的语义;无论完成方式如何实现,只要它已经被实现为将发生,那么它就会发生,垃圾收集器也不会改变这一点。 - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接