微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么同步顺序定义为所有同步操作的总顺序?

如何解决为什么同步顺序定义为所有同步操作的总顺序?

在学习 Java 内存模型时,我对同步顺序 (SO) 的定义感到困惑。据说 SO 是一个执行的所有同步操作 (SA) 的总顺序。但是谈论执行的所有 SA 有什么意义呢?我不知道这对我有什么用。我如何考虑所有 SA?我理解以下声明的含义:

对于每个线程t,同步的同步顺序 t中的actions与t的程序顺序一致。

语句的用处显而易见,我可以轻松使用它。但是 SO 的定义对我来说还不清楚。因此,当涉及到多个线程的 SO 时,我无法弄清楚如何使用它。这让我很担心。你是怎么理解SO的,在写程序的时候是怎么使用的?

解决方法

SO 不是您每天都要处理的事情。它只是构建happens-before关系的基础。

在happens-before 关系中涉及到一些订单。

有程序顺序 (PO):因此在应用任何优化之前,Java 源代码指定的单个线程执行加载/存储的顺序。程序顺序为单个线程的所有加载/存储创建总顺序。但它是一个偏序,因为它没有对不同线程的加载/存储进行排序。

然后是同步顺序(SO):它是所有同步操作(锁获取/释放、易失性加载/存储等)的总顺序。因为每个同步操作都是原子的,它们自动形成一个全序。所以它甚至会命令释放锁 A 和获取锁 B。SO 与 PO 一致。

然后我们有同步 (SW) 顺序:SW 是 SO 的子顺序,因此它只捕获同步关系。例如。如果在 SO 中对 X 的易失性写入在对 X 的易失性读取之前,则同步关系将对这两个进行排序。它实际上会对 X 的写入与 X 的所有后续读取进行排序。但与 SO 不同的是,它会不订购例如X 的易失性写入和 Y 的易失性读取。SW 也将与 PO 一致。

happens-before 顺序被定义为 PO 和 SW 联合的传递闭包。

注 1: SW 和 SO 需要与 PO 一致的原因是我们不希望 SW/SO 说 a->b 而 PO 说 b->a。因为这会导致发生之前关系中的循环,并且会由于因果循环而使其无效。

注2: 为什么同步指令会创建一个总订单?好;他们没有。但是我们可以假设存在一个全序。如果 CPU1 正在执行易失性存储 A,而 CPU2 正在执行易失性存储 B(不同的变量),那么 A、B 不可能有因果关系,因此 A-/->B 和 B-/->A(不不会发生)。所以我们现在有 2 个没有相互排序的动作。很酷的事情是我们可以选择任何订单,因为没有人可以证明否则。一个更具技术性的论点是 SO 是 DAG,并且每个 DAG 总是至少有 1 个拓扑排序,这是一个全序。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。