Unexpected Behaviour with CompletableFuture

Spyros :

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?

Anthony Raymond :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=94750&siteId=1