gpt4 book ai didi

java - 如何理解happens-before一致

转载 作者:行者123 更新时间:2023-12-01 16:52:08 24 4
gpt4 key购买 nike

chapter 17 of JLS ,它引入了一个概念:happens-before 一致。

A set of actions A is happens-before consistent if for all reads r in A, where W(r) is the write action seen by r, it is not the case that either hb(r, W(r)) or that there exists a write w in A such that w.v = r.v and hb(W(r), w) and hb(w, r)"

在我的理解中,它相当于以下几句话:...,情况是既不...也不...

所以我的前两个问题是:

  • 我的理解对吗?
  • “w.v = r.v”是什么意思?

它还给出了一个示例:17.4.5-1

Thread 1 Thread 2

B = 1; A = 2;

r2 = A; r1 = B;

按照第一次执行顺序:

1: B = 1;

3: A = 2;

2: r2 = A; // sees initial write of 0

4: r1 = B; // sees initial write of 0

命令本身已经告诉我们两个线程是交替执行的,所以我的第三个问题是:left number是什么意思?

根据我的理解,r2和r1都可以看到初始写入0的原因是A和B都不是 volatile 字段。所以我的第四个问题是:我的理解是否正确?

按照第二个执行顺序:

1: r2 = A;  // sees write of A = 2

3: r1 = B; // sees write of B = 1

2: B = 1;

4: A = 2;

根据happens-before一致性的定义,不难理解这个执行顺序是happens-before一致的(如果我的第一理解是正确的话)。所以我的第五和第六个问题是:现实世界中是否存在这种情况(读看到稍后发生的写)?如果是的话,你能给我一个真实的例子吗?

最佳答案

每个线程都可以位于不同的核心上,并拥有自己的私有(private)寄存器,Java 可以使用这些寄存器来保存变量的值,除非您强制访问一致的共享内存。这意味着一个线程可以写入存储在寄存器中的值,并且该值在一段时间内对另一个线程不可见,例如循环或整个函数的持续时间。 (毫秒并不罕见)

一个更极端的例子是,读取线程的代码经过优化,假设由于它永远不会更改值,因此不需要从内存中读取它。在这种情况下,优化的代码永远看不到另一个线程执行的更改。

在这两种情况下,使用 volatile 可确保读取和写入以一致的顺序发生,并且两个线程看到相同的值。有时,这被描述为始终从主内存读取,但事实并非如此,因为缓存可以直接相互通信。 (因此对性能的影响比您预期的要小得多)。

在普通 CPU 上,缓存是“一致的”(不能保存陈旧/冲突的值)并且是透明的,不需手动管理。使数据在线程之间可见仅意味着在 asm 中执行实际的加载或存储指令来访问内存(通过数据缓存),并且可以选择等待存储缓冲区耗尽以给出排序。其他后续操作。

关于java - 如何理解happens-before一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61666124/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com