Подтвердить что ты не робот

Является ли оператор-оператор атомарным?

В документации говорится, что вы можете использовать if-else несколько раз или switch-case:

int condition;

setCondition(int condition) {
    this.condition = condition;
}

Либо коммутационный футляр

switch (condition) {
  case 1: print("one"); break;
  case 2: print("two"); break;

или

if (condition == 1) { print("one"); }
else if (condition == 2) { print("two"); }

Далее, condition объявлен volatile, а метод setCondition() вызывается из нескольких потоков. if-else не является атомарным, а volatile переменная write является синхронизирующим действием. Таким образом, в последнем коде могут быть напечатаны как "одна", так и "две" строки.

Этого можно избежать, если была использована локальная переменная метода с начальным значением:

int localCondition = condition;
if (local condition == ..) ..

Оператор switch-case содержит некоторую начальную копию переменной? Как выполняются операции с поперечными потоками?

4b9b3361

Ответ 1

Из спецификация Java в операторах switch:

Когда выполняется оператор switch, сначала вычисляется выражение. [...]

Это говорит о том, что выражение оценивается один раз и что результат временно сохраняется где-то в другом месте, поэтому условия гонки не возможны.

Я не могу найти определенный ответ нигде.


Быстрый тест показывает, что это действительно так:

public class Main {
  private static int i = 0;

  public static void main(String[] args) {
    switch(sideEffect()) {
      case 0:
        System.out.println("0");
        break;
      case 1:
        System.out.println("1");
        break;
      default:
        System.out.println("something else");
    }

    System.out.println(i); //this prints 1
  }

  private static int sideEffect() {
    return i++;
  }
}

И действительно, sideEffect() вызывается только один раз.

Ответ 2

Выражение оценивается один раз при входе в коммутатор.

Коммутатор может использовать результат внутренне столько раз, сколько нужно, чтобы определить, к какому коду перейти. Это сродни:

int switchValue = <some expression>;
if (switchValue == <some case>)
    <do something>
else if (switchValue == <some other case>
    <do something else>
// etc

Собственно, коммутатор компилируется в различные стили байтового кода в зависимости от количества случаев и типа значения.

Переключателю нужно только один раз оценить выражение.