w9n7cxx5fM8
w9n7cxx5fM8

Reputation: 49

Is it safe to check fields after `Future<?>` tasks are finished?

Is it safe to check a field modified by a task executed in a Future<?> after successfully calling future.get() ?
(Is it guaranteed to be finished setting the value, and I'm seeing the new value?)

I would check the field on the same thread as calling the future.get().

Or should I only use the return value of future.get() and should not expect this to work like this?

Example:

class MyData {
    private int a;

    public void setA(int a) { this.a = a; }
    public int getA() { return a; }
}

public class MainClass {
    public static void main(String[] args) {
        final Executor executor = Executors.newFixedThreadPool(15);

        final List<MyData> objects = Arrays.asList(new MyData(), new MyData() /* ... */);

        final Future<Void> future1 = CompletableFuture.supplyAsync(() -> { objects.get(0).setA(1); return null; }, executor);
        final Future<Void> future2 = CompletableFuture.supplyAsync(() -> { objects.get(1).setA(2); return null; }, executor);
        /* ... */

        a.get();
        b.get();
        /* ... */

        // Is it safe here to check the `a` field of the objects?
        assert objects.get(0).getA() == 1;
        assert objects.get(1).getA() == 2;
    }
}

Upvotes: 0

Views: 139

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280181

The javadoc of Future states

Memory consistency effects: Actions taken by the asynchronous computation happen-before actions following the corresponding Future.get() in another thread.

Since get will only return when the corresponding computation completes (the setA invocation and return), that computation is visible through the happen-before relationship to any code after the call to get. Your call to getA occurs after the Future#get, so it'll see the results of the setA which happened before it.

Upvotes: 1

Fossan
Fossan

Reputation: 116

As the documentation of Future#get() says:

Waits if necessary for the computation to complete, and then retrieves its result.

So it is completely safe to do the assertions once calling the Future.get() method since the values will be resolved by then.

Upvotes: 0

Related Questions