切换操作符是原子的吗

时间:2017-01-29 18:10:24

标签: java multithreading if-statement switch-statement conditional-statements

在文档中,据说您可以多次使用if-elseswitch-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是同步动作。因此,“one”和“two”字符串都可以打印在最后一个代码中。

如果使用了一些具有初始值的方法局部变量,则可以避免:

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

switch-case运算符是否包含变量的初始副本?如何用它实现交叉线程操作?

2 个答案:

答案 0 :(得分:17)

Java specification开关语句:

  

执行switch语句时,首先评估Expression。 [...]

这个建议表达式被评估一次,并且结果暂时保存在其他地方,因此不可能有竞争条件。

我无论如何都找不到明确的答案。

快速测试表明情况确实如此:

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()只被调用一次。

答案 1 :(得分:14)

进入交换机时,一次评估表达式。

交换机可以在内部使用结果,因为它需要多次确定要跳转到的代码。它类似于:

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

实际上,根据案例数量和值的类型,交换机可以编译为各种字节码样式。

交换机只需要评估一次表达式。