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;
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
按照正常的理解,只会有三种结果,但运行的实际结果如下:
java
r2 == 0, r1 == 1
r2 == 2, r1 == 0
r2 == 0, r1 == 0
r2 == 2, r1 == 1
1
2
3
4
2
3
4
出现第四种情况的原因是指令可能被重排为下图中右侧的形式,此时就可能会出现上面的第四种情况。
将变量定义为volatile
后,将只可能出现前三种情况:
java
private volatile int A, B, r1, r2;
1
java
r2 == 0, r1 == 1
r2 == 2, r1 == 0
r2 == 0, r1 == 0
1
2
3
2
3