Java 重排序对多线程的影响

来自姬鸿昌的知识库
Jihongchang讨论 | 贡献2023年3月2日 (四) 02:50的版本 (建立内容为“<syntaxhighlight lang="java"> public class ReorderExample { int a = 0; boolean flag = true; public void writer() { a = 1; // 1 flag…”的新页面)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索
public class ReorderExample {

    int a = 0;
    boolean flag = true;

    public void writer() {
        a = 1; // 1
        flag = true; // 2
    }

    public void reader() {
        if (flag) { // 3
            int i = a * a;
        }
    }

}

flag 变量是个标记,用来标识变量 a 是否已被写入。

这里假设有两个线程 A 和 B,A 首先执行 writer() 方法,随后 B 线程接着执行 reader() 方法。

线程 B 在执行操作 4(int i = a * a;)时,能否看到线程 A 在操作 1(a = 1;) 对共享变量 a 的写入呢?

答案是:不一定能看到

由于操作 1 和操作 2 没有数据依赖关系,编译器和处理器可以对这两个操作重排序;

同样,操作 3 和操作 4 没有数据依赖关系,编译器和处理器也可以对这两个操作重排序。

当操作 1 和操作 2 重排序时,可能会产生什么效果?看下图: