java - 并发导致的不同输出
问题描述
public class InstructionReorder {
public int v1=1;
public int v2=1;
void foo() {
v1 = v2+1;
v2 = 0;
System.out.println(String.format("%d and %d",v1,v2));
}
public static void main(String[] args) throws Exception {
final InstructionReorder ir = new InstructionReorder();
for (int i=0;i<Runtime.getRuntime().availableProcessors()>>2;i++) {
new Thread(ir::foo).start();
}
Thread.sleep(1000);
}
}
代码有不同的输出,有时会得到 output1:
2 and 0
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
或者有时得到输出2:
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
1 and 0
output1 是预期的结果。如果我同步方法,我得到了 output1,但我不想使用锁。我尝试了 volatile,但没有效果。
没有锁怎么修?
解决方案
您看到的行为与指令重新排序无关,而是与并发访问有关。如果您想用 Java 编写正确的多线程代码,请查看“Java Concurrency in Practice”。
简而言之,您只需要使用一个同步块进行 v1 和 v2 访问。
推荐阅读
- r - 使用 gganimate 的动画图
- ios - 如何实现双击以获取更多信息等进一步操作?
- c++ - 为什么这段代码会触发一定位数的断点?
- arduino - AT+UHTTPC 命令中的变量
- javascript - 是否可以使用 HOC 将字符串数组作为参数传递?
- angular - 函数在第二次调用时被记录
- javascript - 更改 javascript html,使用 jquery css
- ios - Swift 5.1 Opaque Result Types 如何与旧操作系统(例如 iOS 12)交互
- reactjs - 事件处理程序未执行计算
- wordpress - 如何在高级自定义字段插件中使用用户字段类型显示用户名