问题描述:学Java虚拟机的内存模型的时候学到long和double分别存储于两个变量槽中,已知单个变量槽的修改操作是原子性的,long和double占据两个变量槽,想要模拟两个线程,一个修改高32位,一个修改低32位,出long和double不断修改后出现未知数值的情况
public class Test {
private static volatile int a = 65537;
public static void main(String[] args) {
new Thread(() -> {
while (true) {
if (a == 65538) {
a = 65537;
System.out.println("修改");
} else if (a == 65537) {
continue;
} else {
try {
throw new Exception("线程1出问题了"+a);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}).start();
new Thread(()->{
while (true) {
if (a == 65537) {
a = 65538;
System.out.println("修改");
} else if (a == 65538) {
continue;
} else {
try {
throw new Exception("线程2出问题了"+a);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}).start();
}
}
修改
java.lang.Exception: 线程1出问题了65538
at cn.luckycurve.Test.lambda$main$0(Test.java:20)
at java.base/java.lang.Thread.run(Thread.java:834)
修改
修改
修改
修改
java.lang.Exception: 线程2出问题了65537
at cn.luckycurve.Test.lambda$main$1(Test.java:38)
at java.base/java.lang.Thread.run(Thread.java:834)
这里使用volatile是为了保证变量的可见性(基于happen before规则),不过后来在网上查询得知:由于Java内存模型保证声明为volatile的long和double变量的get和set操作是原子性的,实验失败。