切换操作符是原子的吗

awf*_*fun 17 java multithreading if-statement switch-statement conditional-statements

在文档中,据说您可以if-else多次使用或者switch-case:

int condition;

setCondition(int condition) {
    this.condition = condition;
}
Run Code Online (Sandbox Code Playgroud)

交换机箱

switch (condition) {
  case 1: print("one"); break;
  case 2: print("two"); break;
Run Code Online (Sandbox Code Playgroud)

要么

if (condition == 1) { print("one"); }
else if (condition == 2) { print("two"); }
Run Code Online (Sandbox Code Playgroud)

接下来,condition声明volatilesetCondition()从多个线程调用方法. If-else不是原子和volatile变量write是同步动作.因此,"one"和"two"字符串都可以在最后一个代码中打印出来.

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

int localCondition = condition;
if (local condition == ..) ..
Run Code Online (Sandbox Code Playgroud)

switch-case操作员是否持有一些变量的初始副本?如何用它实现交叉线程操作?

Tod*_*ell 17

从关于switch语句的Java规范:

执行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++;
  }
}
Run Code Online (Sandbox Code Playgroud)

事实上,sideEffect()只被调用一次.

  • 想想另一种方式:如果我们写了`switch(someFunctionWithSideEffect())`,那么switch语句最好一次评估该函数** (6认同)

Boh*_*ian 14

进入交换机时,表达式将被评估一次.

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

int switchValue = <some expression>;
if (switchValue == <some case>)
    <do something>
else if (switchValue == <some other case>
    <do something else>
// etc
Run Code Online (Sandbox Code Playgroud)

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

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