如果线程 B 希望看到线程 A 所做的更改,是否只能将最后的更改更改为 volatile 变量而不是全部?
If Thread B wishes to see changes Thread A makes, can only the last change be to a volatile variable as opposed to all?
我看过 this answer,它说明了如何:
Under the new memory model, when thread A writes to a volatile
variable V, and thread B reads from V, any variable values that were
visible to A at the time that V was written are guaranteed now to be
visible to B.
因此,举个例子:
public class Main {
static int value = -1;
static volatile boolean read;
public static void main(String[] args) {
Thread a = new Thread(() -> {
value = 1;
read = true;
});
Thread b = new Thread(() -> {
while (!read);
System.out.println("Value: " + value);
});
a.start();
b.start();
}
}
尽管 value
的非易失性(仅 read
),value
的变化(从 -1 到 1)是否保证对线程 b 可见?
如果是这样,考虑到为了让另一个线程可见而执行的一系列更改,除了最后一个变量之外,是否有任何目的让任何变量发生变化?
是的,对 value
的更改保证对线程 b 可见。
JLS 17.4.4. Synchronization Order 说:
- A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).
JLS 17.4.5. Happens-before Order 说:
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
If we have two actions x and y, we write hb(x, y) to indicate that x happens-before y.
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
There is a happens-before edge from the end of a constructor of an object to the start of a finalizer (§12.6) for that object.
If an action x synchronizes-with a following action y, then we also have hb(x, y).
If hb(x, y) and hb(y, z), then hb(x, z).
项目符号 1 说 value = 1
发生在 read = true
.
之前
项目符号 3 说 read = true
发生在 !read
.
之前
项目符号 1 表示 !read
发生在 "Value: " + value
.
之前
项目符号 4 说 value = 1
happens-before "Value: " + value
.
我看过 this answer,它说明了如何:
Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B.
因此,举个例子:
public class Main {
static int value = -1;
static volatile boolean read;
public static void main(String[] args) {
Thread a = new Thread(() -> {
value = 1;
read = true;
});
Thread b = new Thread(() -> {
while (!read);
System.out.println("Value: " + value);
});
a.start();
b.start();
}
}
尽管 value
的非易失性(仅 read
),value
的变化(从 -1 到 1)是否保证对线程 b 可见?
如果是这样,考虑到为了让另一个线程可见而执行的一系列更改,除了最后一个变量之外,是否有任何目的让任何变量发生变化?
是的,对 value
的更改保证对线程 b 可见。
JLS 17.4.4. Synchronization Order 说:
- A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).
JLS 17.4.5. Happens-before Order 说:
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
If we have two actions x and y, we write hb(x, y) to indicate that x happens-before y.
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
There is a happens-before edge from the end of a constructor of an object to the start of a finalizer (§12.6) for that object.
If an action x synchronizes-with a following action y, then we also have hb(x, y).
If hb(x, y) and hb(y, z), then hb(x, z).
项目符号 1 说 value = 1
发生在 read = true
.
之前
项目符号 3 说 read = true
发生在 !read
.
之前
项目符号 1 表示 !read
发生在 "Value: " + value
.
之前
项目符号 4 说 value = 1
happens-before "Value: " + value
.