Параллелизм Java: изменения, внесенные задачей, переданной исполнителю, видны после future.get ()

1

Предположим, что задача, представленная в пул исполнителей, выглядит

class Task implements Future<Boolean> {
 public HeavyClass heavyClass;
 public Task(HeavyClass heavyClass) {
    this.heavyClass = heavyClass;
 }

 public Boolean call() {
   try {
     //do changes to heavyClass
     return true;
   } catch(Exception e) {
      return false;
   }
 }

NOw в вызывающем потоке, который я делаю

Future<boolean> future = executor.submit(new Task(heavyClass));
try {
  boolean success = future.get();
  if (success) {
      //Assume all changes made to heavyClass are visible
  }
}

Это верно? По моему мнению, это не совсем правильно. Каков наилучший способ обеспечить исправление в таких сценариях?

Теги:
concurrency
visibility

2 ответа

2

Это должно быть хорошо. Любая жизнеспособная реализация Future должна быть написана таким образом, что ее завершение включает в себя забор, а проверка на завершение включает в себя приобретение забора. Все предыдущие изменения в вашем heavyClass должны быть heavyClass, если Future будет отмечено как завершенное и должно быть гарантировано видимым для других потоков к моменту завершения состояния задачи.

Опора на это, конечно, означает доверие к тому, что тот, кто реализовал исполнителя, знал, что они делают. Если вы используете одного из основных исполнителей Java, вы должны быть в порядке.

1

Одна из приятных вещей в Future заключается в том, что вам не нужно беспокоиться об этом вопросе. Из документации:

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

Поэтому, несмотря на то, что ваша задача не делает ничего для обеспечения видимости результатов между потоками, реализация Executor позаботится об этом для вас.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню