Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSR-133 cookbook如何执行Java内存模型所做的所有保证_Java_Multithreading_Concurrency_Cpu_Cpu Cache - Fatal编程技术网

JSR-133 cookbook如何执行Java内存模型所做的所有保证

JSR-133 cookbook如何执行Java内存模型所做的所有保证,java,multithreading,concurrency,cpu,cpu-cache,Java,Multithreading,Concurrency,Cpu,Cpu Cache,我的理解是,这是一个引用得很好的指南,介绍了如何使用一系列内存障碍(或至少是可见性保证)实现Java内存模型 根据对不同类型屏障的描述,我的理解是,StoreLoad是唯一一个能够保证所有CPU缓冲区都被刷新到缓存中,从而确保新读取(通过避免存储转发)并保证由于缓存一致性而观察到最新值的屏障 我正在查看易失性/常规存储/加载的不同程序顺序交互所需的特定屏障表,以及所需的内存屏障 根据我的直觉,这张表似乎不完整。例如,Java内存模型保证监视器的acquire操作在另一个线程中发布之前执行的所有操

我的理解是,这是一个引用得很好的指南,介绍了如何使用一系列内存障碍(或至少是可见性保证)实现Java内存模型

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

我正在查看易失性/常规存储/加载的不同程序顺序交互所需的特定屏障表,以及所需的内存屏障

根据我的直觉,这张表似乎不完整。例如,Java内存模型保证监视器的acquire操作在另一个线程中发布之前执行的所有操作的可见性,即使更新的值是非易失性的。在上面链接中的表中,似乎刷新CPU缓冲区和传播更改/允许观察新更改的唯一操作是Volatile Store或MonitorExit,然后是Volatile Load或MonitorEnter。在上面的示例中,我看不出屏障如何保证可见性,因为这些操作(根据表)仅使用LoadStore和StoreStore,据我所知,它们只涉及线程中的重新排序,不能强制执行“发生在保证之前”(即跨线程)

我在这里的理解哪里出错了?或者,此实现是否仅强制在获取/释放监控器时执行同步保证或额外操作之前执行


感谢

文档中的障碍是抽象概念,它们或多或少映射到不同CPU上的不同事物。但它们只是指导方针。JVM实际上必须遵循JLS第17章中的规则

障碍作为一个概念也是“全球性”的,因为它们对所有之前和之后的指示进行排序

例如,Java内存模型保证监视器的acquire操作在另一个线程中发布之前执行的所有操作的可见性,即使更新的值是非易失性的

获取一个监视器是在cookbook中输入的监视器,它只需要对锁上争用的其他线程可见。监视器出口是释放动作,它将防止之前的负载和存储从其下方移动。您可以在cookbook表中看到这一点,其中第一个操作是正常加载/存储,第二个是易失性存储或监视器出口

在具有总存储顺序的CPU上,存储缓冲区(如果可用)对正确性没有影响;只看性能

在任何情况下,JVM都可以使用提供JLS所需的原子性和可见性语义的指令。这就是关键:如果您编写Java代码,那么您将针对JLS中定义的抽象机器进行编码。如果只对抽象机器进行编码不能提供所需的性能,那么您只能深入了解具体机器的实现细节。你不需要为了正确而去那里

StoreLoad是唯一一个保证将所有CPU缓冲区刷新到缓存中,从而确保新读取(通过避免存储转发)并保证由于缓存一致性而观察到最新值的缓冲区

对于x86体系结构来说,这可能是正确的,但您不应该考虑这种抽象级别。在这种情况下,对于要执行的处理器来说,缓存一致性可能代价高昂

以移动设备为例,一个重要的目标是减少电池使用量。在这种情况下,它们可能不参与缓存一致性,并且
StoreLoad
会丢失此功能

在上面的示例中,我看不出屏障如何保证可见性,因为这些操作(根据表)仅使用LoadStore和StoreStore,据我所知,它们只涉及线程中的重新排序,不能强制执行“发生在保证之前”(即跨线程)

让我们考虑一个易失性字段。易变的加载和存储看起来如何?好吧,但我要一份

易失性存储和随后的加载如下所示:

<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>

[商店]
[装载库]
x=1;//挥发性存储器
[StoreLoad]//案例(a):易失性存储后的防护
...
[StoreLoad]//案例(b):在易失性负载之前进行保护
int t=x;//不稳定负荷
[载货]
[装载库]
因此,
可以是非易失性写入,但正如您所看到的,这些写入在易失性存储之前提交到内存中。然后,当我们准备读取
LoadLoad
LoadStore
时,将强制等待,直到
volatile store
成功


最后,前后的
StoreLoad
确保了如果volatile load和store紧跟在前面,那么它们就不能重新排序。

我不确定你从哪里得到的
StoreLoad
屏障是唯一强制执行某些特定行为的类型。所有的障碍,从抽象上来说,都严格执行了它们定义要执行的内容。例如,
LoadLoad
防止任何先前加载与任何后续加载重新排序

可能存在特定于体系结构的关于如何实施特定屏障的描述:例如,在x86上,除StoreLoad之外的所有屏障都不是ops,因为芯片体系结构会自动实施其他顺序,而
StoreLoad
通常作为存储缓冲区刷新来实现。尽管如此,所有的障碍都有其抽象的定义,这是独立于体系结构的,烹饪书就是根据这一定义来定义的,并将概念障碍映射到实际的ISA特定实现

特别是,即使存在障碍物