<!-- # JSR 133 图1 --> <!-- jsr-133-figure-01 --> 今天写了段代码验证 [JSR-133][1] 中的第一个图例,确实如文件中描述的,出现了预想外的结果。  示例代码如下,使用`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 ``` [1]:https://jcp.org/en/jsr/detail?id=133 (JSR 133: JavaTM Memory Model and Thread Specification Revision) Loading... 版权声明:本文为博主「佳佳」的原创文章,遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://www.liujiajia.me/2021/8/13/jsr-133-figure-01 提交