JSR 133 图 1
🏷️ JSR
今天写了段代码验证 JSR-133 中的第一个图例,确实如文件中描述的,出现了预想外的结果。
示例代码如下,使用CountDownLatch
来尽量使两个线程中的处理同时开始。
java
package me.liujiajia.sample.multi.thread.sample;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
public class MultiThreadSample001 {
private static int A, B, r1, r2;
public static void main(String[] args) throws InterruptedException {
Set<String> resultSet = new HashSet<>();
while (true) {
A = 0;
B = 0;
r1 = 0;
r2 = 0;
CountDownLatch startCount = new CountDownLatch(2);
CountDownLatch endCount = new CountDownLatch(2);
Thread t1 = new Thread(() -> {
try {
startCount.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
r2 = A;
B = 1;
endCount.countDown();
});
Thread t2 = new Thread(() -> {
try {
startCount.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
r1 = B;
A = 2;
endCount.countDown();
});
t1.start();
startCount.countDown();
t2.start();
startCount.countDown();
endCount.await();
String result = String.format("%d%d", r2, r1);
if (!resultSet.contains(result)) {
resultSet.add(result);
System.out.println(String.format("r2 == %d, r1 == %d", r2, r1));
if (resultSet.size() >= 4) {
break;
}
}
}
}
}
按照正常的理解,只会有三种结果,但运行的实际结果如下:
java
r2 == 0, r1 == 1
r2 == 2, r1 == 0
r2 == 0, r1 == 0
r2 == 2, r1 == 1
出现第四种情况的原因是指令可能被重排为下图中右侧的形式,此时就可能会出现上面的第四种情况。
将变量定义为volatile
后,将只可能出现前三种情况:
java
private volatile int A, B, r1, r2;
java
r2 == 0, r1 == 1
r2 == 2, r1 == 0
r2 == 0, r1 == 0