JSR-133烹饪书如何实施Java内存模型的所有保证

我的理解是,
JSR-133 cookbook是如何使用一系列内存障碍(或至少是可见性保证)实现Java内存模型的引用指南.

基于对不同类型障碍的描述,我的理解是,StoreLoad是唯一一个保证所有CPU缓冲区都被刷新到缓存并因此确保新读取(通过避免存储转发)并保证观察最新值的由于缓存一致性.

我正在查看易失性/常规存储/负载的不同程序顺序交叉所需的特定障碍表以及需要哪些内存障碍.

根据我的直觉,这张桌子似乎不完整.例如,Java内存模型保证监视器的获取操作对在另一个线程中释放之前执行的所有操作的可见性,即使更新的值是非易失性的.在上面链接的表中,似乎只有刷新CPU缓冲区并传播更改/允许观察到新更改的唯一操作是Volatile Store或MonitorExit,后跟Volatile Load或MonitorEnter.在上面的例子中,当这些操作(根据表格)仅使用LoadStore和StoreStore时,我没有看到障碍如何保证可见性,根据我的理解,这只涉及在线程中重新排序并且不能强制执行之前发生的事情保证(跨线程).

我的理解在哪里出错了?或者此实现仅在以前执行,而不是同步保证或获取/释放监视器上的额外操作.

谢谢

最佳答案

StoreLoad is the only one that guarantees all CPU buffers are flushed to cache and therefore ensure fresh reads (by avoiding store forwarding) and guarantees the observation of the latest value due to cache coherency.

对于x86体系结构可能也是如此,但您不应该考虑这种抽象级别.情况可能是高速缓存一致性对于处理器执行来说可能是昂贵的.

以移动设备为例,一个重要目标是减少电池使用程序消耗的数量.在这种情况下,他们可能不参与缓存一致性,而StoreLoad会丢失此功能.

I don’t see how the barriers could guarantee visibility in my above example, when those operations (according to the table) only use LoadStore and StoreStore which from my understanding are only concerned with re-ordering in a thread and cannot enforce the happens before guarantee (across threads that is).

我们只考虑一个不稳定的领域.易变的负载和存储看起来如何?好吧,Aleksey Shipilëv has a great write up on this,但我会拿一块.

易失性存储然后后续加载看起来像:

<other ops>
[StoreStore]
[LoadStore]
x = 1; // volatile store
[StoreLoad] // Case (a): Guard after volatile stores

...

[StoreLoad] // Case (b): Guard before volatile loads
int t = x; // volatile load
[LoadLoad]
[LoadStore]
<other ops>

那么, 可以是非易失性写入,但正如您所看到的那些写入在volatile存储之前被提交到内存.然后当我们准备好读取LoadLoad时,LoadStore将强制等待,直到volatile存储成功.

最后,StoreLoad之前和之后确保易失性加载和存储如果紧接在彼此之前则不能重新排序.

点赞