Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is switch operator atomic?

In documentation it is said you could equally use if-else multiple times or switch-case:

int condition;

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

Either switch-case

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

or

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

Next, conditionis declared volatile and method setCondition() is called from multiple threads. If-else is not atomic and volatile variable write is a synchronizing action. So both "one" and "two" string could be printed in the last code.

It could be avoided if some method local variable with initial value was used:

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

Does switch-case operator hold some initial copy of variable? How are cross threads operations implemented with it?

like image 518
awfun Avatar asked Jan 29 '17 18:01

awfun


People also ask

Is assignment operator Atomic?

no, its not..... you need to use a locking primitive of some sort.

Is the ++ operator Atomic?

On objects without an atomic type, standard never defines ++ as an atomic operation.

Is += an atomic operation?

For the change in value to be visible across cores, a += (for instance) would have to load the value, add the increment and then store it. This means that the operation will not be atomic. To ensure atomicity you'd need to put appropriate locking around the operation.

What are atomic types in Java?

The most commonly used atomic variable classes in Java are AtomicInteger, AtomicLong, AtomicBoolean, and AtomicReference. These classes represent an int, long, boolean, and object reference respectively which can be atomically updated.


1 Answers

From the Java specification on switch statements:

When the switch statement is executed, first the Expression is evaluated. [...]

This suggests that the expression is evaluated once and that the result is temporarily kept somewhere else, and so no race-conditions are possible.

I can't find a definite answer anywhere though.


A quick test shows this is indeed the case:

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

And indeed, sideEffect() is only called once.

like image 78
Todd Sewell Avatar answered Sep 24 '22 13:09

Todd Sewell