【问题标题】:How to understand the synchronization order which is a total order?如何理解同步顺序是总顺序?
【发布时间】:2017-06-15 11:09:30
【问题描述】:

在 JLS17.4.4 中,它说

每次执行都有一个同步顺序。同步顺序是执行的所有同步操作的总顺序。

我知道什么是总订单。而且我知道需要订购同步操作。但这里让我感到困惑的是为什么它是 ALL 同步操作的总顺序。例如,监视器 m 上的解锁操作发生在 m 上的所有后续锁定操作之前。但是如果同时在监视器n上有一个锁定动作,是否需要在监视器m的解锁动作之后排序?如果不是,那为什么所有的同步动作都可以有一个总顺序?谢谢。

【问题讨论】:

    标签: java multithreading synchronization


    【解决方案1】:

    很好的问题。虽然我不确定答案,但我认为最符合我理解的解释是肯定的,两个不同的锁之间存在“同步顺序”,因为JLS 17.4.2 定义了描述为按“同步顺序”排序的操作" 必须是线程间的(因此一个线程必须在另一个线程接收到它之前调度该操作)。

    但是,这里有一个问题:

    同步动作在动作上产生synchronized-with关系,定义如下[...]

    只有由 synchronized-with 排序的操作会产生所需/期望的记忆效果(即推进缓存状态)。

    因此,基本上虽然您所有的“同步操作”都遵循“同步顺序”(因此也是“总顺序”),但只有那些 synchronized-with 模式对线程安全有效。 p>

    【讨论】:

    • 首先,非常感谢您的回复。我想你的观点启发了我。这是我正在考虑的内容:来自 17.4.3 “如果所有操作都以与程序顺序一致的总顺序(执行顺序)发生,则一组操作是顺序一致的。”而且 JMM 在语义上是顺序一致的,这是通过同步操作同步比赛数据来确保的。所以同步动作有一个总的顺序来保证JMM的顺序一致性。我在这里对总订单的理解是关于同步操作的可见性。
    • 总结一下。虽然在理论上考虑 JMM 那样工作是有用的,但实际上我真的想不出这样一个微小的细节会有用的地方。线程间操作以这种方式运行的事实可能甚至不是 JMM 的副作用,但更有可能是当今大多数 CPU 缓存的工作方式(如果我错了,请纠正我)。无论哪种方式,如果你觉得这个细节对你的职业或项目或其他什么有用,我很想你分享:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2019-09-02
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多