I am trying to create a simple example with async CompletableFuture's but I'm seeing some weird behaviour. The idea is that I kick off 2 async futures, one activates a boolean flag after a set time and the other polls that flag to release the value once thread 1 has changed that flag. Here's my code:
package completablefutures;
import java.util.concurrent.CompletableFuture;
public class CFMain throws InterruptedException {
public static void main(String... args) {
CF cf = new CF();
CompletableFuture.supplyAsync(cf::getCompletable).thenRun(() -> System.out.println("Post-future action"));
CompletableFuture.supplyAsync(cf::doSleep);
Thread.sleep(10000);
}
}
And the CF class:
package completablefutures;
public class CF {
private boolean valueIsSafe = false;
public boolean getCompletable() {
System.out.println("Fetching completable");
while(true) {
if(this.valueIsSafe) {
System.out.println("Completable fetched");
return true;
}
}
}
public boolean doSleep() {
System.out.println("Started sleeping");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.valueIsSafe = true;
System.out.println("Finished sleeping");
return true;
}
}
When I let the program run it's course, it prints this:
Fetching completable
Started sleeping
Finished sleeping
Process finished with exit code 0
i.e. the future never completes in the 10s allocated. So what's going on here?
You are accessing the valueIsSafe from multiple threads, you must define this variable as volatile.
private volatile boolean valueIsSafe = false;
Using the volatile keyword will prevent threads from caching this value and force them to read the raw memory on every access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With