在文档中,据说您可以多次使用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是同步动作。因此,“one”和“two”字符串都可以打印在最后一个代码中。
如果使用了一些具有初始值的方法局部变量,则可以避免:
int localCondition = condition;
if (local condition == ..) ..
switch-case
运算符是否包含变量的初始副本?如何用它实现交叉线程操作?
答案 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
实际上,根据案例数量和值的类型,交换机可以编译为各种字节码样式。
交换机只需要评估一次表达式。