在32位的java虚拟中,Long,Double类型的数据写入主内存的动作并不是原子性的,所以在并发环境中可能会出现读取到一半的值的情况,先写一个程序来进行测试
package com.demo;
/**
* @Description: Long类型的变量在32位虚拟机中的读写原子性测试
*/
public class LongRWIn32Demo implements Runnable {
private static long testVal = 0;
private long val;
public LongRWIn32Demo(long val) {
this.val = val;
}
@Override
public void run() {
while (!Thread.interrupted()) {
testVal = val;
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new LongRWIn32Demo(-1));
Thread t2 = new Thread(new LongRWIn32Demo(0));
System.out.println(Long.toBinaryString(-1));
System.out.println(format(Long.toBinaryString(0), 64));
t1.start();
t2.start();
long switchVal;
while ((switchVal = testVal) == -1 || switchVal == 0) {
System.out.println("loop ...");
}
System.out.println(format(Long.toBinaryString(switchVal), 64));
System.out.println(switchVal);
t1.interrupt();
t2.interrupt();
}
private static String format(String value, int targetLength) {
int n = targetLength - value.length();
for (int x = 0; x < n; x++) {
value = "0" + value;
}
return value;
}
}
可以看到,读取32位数据的情况。
为了避免这种情况,可以使用volatile关键字,被此关键字修饰的变量在读写时将保持原子性。
本例中修饰 testVal 即可