Reputation: 11569
I want to run a CompletableFuture property on a given class. If i have initialized like so, would that be dangerous and possibly create a partially constructed object?
public class MyClass {
public final CompletableFuture<BigDecimal> myExpensiveVal = CompletableFuture.supplyASync(() -> calculateExpensiveMethod(this));
//...
}
Upvotes: 0
Views: 77
Reputation: 298479
CompletableFuture.supplyASync
sends the provided Supplier
to another thread and, of course, if this supplier has any reference to your instance under construction, it is a leakage of this
which makes an incomplete object instance visible to other threads and even voids any final
publication guaranty.
In this special case it’s so obvious that you can spot this escaping reproducibly:
public class EscapingThis {
public final CompletableFuture<BigDecimal> myExpensiveVal
= CompletableFuture.supplyAsync(() -> calculateExpensiveMethod(this));
final int fourtyTwo;
public EscapingThis() {
System.out.println(Thread.currentThread()+" starts creating "+this);
try {
myExpensiveVal.get();
} catch (InterruptedException|ExecutionException ex) {
Logger.getLogger("EscapingThis").log(Level.SEVERE, null, ex);
}
System.out.println("still incomplete");
fourtyTwo=42;
System.out.println("leaving constructor");
}
static BigDecimal calculateExpensiveMethod(EscapingThis instance) {
System.out.println(Thread.currentThread()
+" says: hello incomplete instance "+instance);
System.out.println("fourtyTwo = "+instance.fourtyTwo);
return BigDecimal.ONE;
}
public static void main(String... arg) {
new EscapingThis();
}
}
Here you will see hello incomplete instance EscapingThis@1a9515
and fourtyTwo = 0
before still incomplete
and leaving constructor
for sure. But you might even see the Thread[main,5,main] starts creating …
message after the hello incomplete …
message as the timing is undefined.
Note that if calculateExpensiveMethod
is an instance method, it doesn’t need the this
parameter to let the instance leak. The implied reference to this
on which the instance method will be invoked is also a leaking reference.
Upvotes: 1