Безопасно ли проверять поля после `Future? `задачи завершены? - PullRequest
0 голосов
/ 10 октября 2019

Безопасно ли проверять поле, измененное задачей, выполненной в Future<?> после успешного вызова future.get()?
(Гарантируется ли завершение установки значения, и я вижу новое значение? )

Я бы проверил поле в том же потоке, что и вызов future.get().

Или я должен использовать только возвращаемое значение future.get() и не должен ожидать, что это будет работать так?

Пример:

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;
    }
}

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

Javadoc Future состояний

Эффекты согласованности памяти : действия, предпринятые асинхронным вычислением произойти до действия, следующие за соответствующим Future.get() в другом потоке.

, поскольку get вернется только после завершения соответствующего вычисления (вызов setA и return),что вычисления видны через отношение случай-до к любому коду после вызова get. Ваш звонок на getA происходит после Future#get, поэтому он увидит результаты setA, произошедшего до него.

0 голосов
/ 10 октября 2019

Как сказано в документации Future#get():

Ожидает, если необходимо, чтобы вычисление завершилось, и затем извлекает его результат.

Так что это абсолютно безопасносделать утверждения один раз, вызвав метод Future.get(), поскольку к тому времени значения будут разрешены.

...