问题描述
在 第 17 章JLS,它引入了一个概念:happens-before 一致性.
In chapter 17 of JLS, it introduce a concept: happens-before consistent.
如果对于 A 中的所有读取 r,其中 W(r) 是 r 看到的写入操作,则一组动作 A 是发生前一致的,如果 hb(r, W(r))或者在 A 中存在写 w 使得 wv = rv 和 hb(W(r), w) 和 hb(w, r)"
在我的理解中,它等于以下几个词:...,情况是既不 ... 也不 ...
In my understanding, it equals to following words:..., it is the case that neither ... nor ...
所以我的前两个问题是:
So my first two questions are:
- 我的理解对吗?
- w.v = r.v"是什么意思?
它还给出了一个例子:17.4.5-1
It also gives an Example: 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是什么意思?
The order itself has already told us that two threads are executed alternately, so my third question is: what does left number mean?
在我的理解中,r2 和 r1 都可以看到初始写入 0 的原因是 A 和 B 都不是 volatile 字段.所以我的第四个问题是:我的理解是否正确?
In my understanding, the reason of both r2 and r1 can see initial write of 0 is both A and B are not volatile field. So my fourth quesiton is: whether my understanding is right?
按第二个执行顺序:
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 一致性(如果我的第一个理解是正确的).所以我的第五和第六个问题是:现实世界中是否存在这种情况(读后写)?如果是这样,你能给我一个真实的例子吗?
According to definition of happens-before consistency, it is not difficult to understand this execution order is happens-before consistent(if my first understanding is correct).So my fifth and sixth questions are: does it exist this situation (reads see writes that occur later) in real world? If it does, could you give me a real example?
推荐答案
每个线程都可以在不同的内核上,并拥有自己的私有寄存器,Java 可以使用这些寄存器来保存变量的值,除非您强制访问一致的共享内存.这意味着一个线程可以写入存储在寄存器中的值,并且该值在一段时间内对另一个线程不可见,例如循环或整个函数的持续时间.(毫秒并不少见)
Each thread can be on a different core with its own private registers which Java can use to hold values of variables, unless you force access to coherent shared memory. This means that one thread can write to a value storing in a register, and this value is not visible to another thread for some time, like the duration of a loop or whole function. (milli-seconds is not uncommon)
一个更极端的例子是读取线程的代码经过优化,假设因为它永远不会改变值,所以不需要从内存中读取它.在这种情况下,优化后的代码永远不会看到另一个线程执行的更改.
A more extreme example is that the reading thread's code is optimised with the assumption that since it never changes the value, it doesn't need to read it from memory. In this case the optimised code never sees the change performed by another thread.
在这两种情况下,volatile
的使用确保读取和写入以一致的顺序发生,并且两个线程看到相同的值.这有时被描述为总是从主内存读取,尽管不一定是这种情况,因为缓存可以直接相互通信.(因此性能损失比您预期的要小得多).
In both cases, the use of volatile
ensures that reads and write occur in a consistent order and both threads see the same value. This is sometimes described as always reading from main memory, though it doesn't have to be the case because the caches can talk to each other directly. (So the performance hit is much smaller than you might expect).
在普通 CPU 上,缓存是一致的"(不能保存陈旧/冲突的值)且透明,而不是手动管理.使数据在线程之间可见仅意味着在 asm 中执行实际加载或存储指令以访问内存(通过数据缓存),并可选择等待存储缓冲区耗尽以提供排序 wrt.其他后续操作.
On normal CPUs, caches are "coherent" (can't hold stale / conflicting values) and transparent, not managed manually. Making data visible between threads just means doing an actual load or store instruction in asm to access memory (through the data caches), and optionally waiting for the store buffer to drain to give ordering wrt. other later operations.
这篇关于如何理解发生前一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!