7

I'd like to fire many one-off async CompletableFutures, like so:

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

Ideally these CompletableFutures could be garbage collected after whenComplete has finished. But is there a risk they are collected beforehand, since I'm not storing a reference?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
kantianethics
  • 671
  • 5
  • 21
  • 1
    During the mark phase all objects that are reachable from Java threads, native handles and other root sources are marked as alive, as well as the objects that are reachable from these objects and so forth. This process identifies and marks all objects that are still used, and the rest can be considered garbage. – tsolakp Feb 15 '19 at 17:44
  • Note that there's a special case that when `main()` returns, they don't need to be completed: https://stackoverflow.com/questions/55267451/main-thread-exits-before-the-completion-of-completablefuture – user202729 Apr 22 '22 at 02:58

1 Answers1

12

You're not explicitly storing a reference, but supplyAsync is, internally. The method creates a CompletableFuture and submits a task to the ForkJoinPool (if you're using the common pool) that has a reference back to it. The CompletableFuture returned by whenComplete becomes a dependent on that first CompletableFuture and so is also referenced.

All these objects will be available for garbage collection once the ForkJoinPool completes execution of the Supplier, marks the first CompletableFuture as complete, triggers the second CompletableFuture, and executes the BiConsumer passed to whenComplete.

You're safe.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • I checked the source for `supplyAsync`, and can confirm that the AsyncSupply runnable submitted to the Executor holds the reference to the CompletableFuture. – kantianethics Feb 15 '19 at 18:18
  • 2
    Or in short, the garbage collector does not change the semantics of a program; it doesn’t matter how the completion has been implemented, as it has been implemented in a way that it will happen, hence it will happen, and the garbage collector will not change that. – Holger Feb 18 '19 at 13:04