Java 如果线程B希望看到线程A所做的更改,那么最后一次更改是否只能是一个可变变量,而不是全部?
我已经看过了,它说明了如何: 在新的内存模型下,当线程A写入易失性 变量V,线程B从V读取 在编写V时A是可见的,现在保证是可见的 B可见 因此,举一个例子:Java 如果线程B希望看到线程A所做的更改,那么最后一次更改是否只能是一个可变变量,而不是全部?,java,multithreading,volatile,java-memory-model,memory-visibility,Java,Multithreading,Volatile,Java Memory Model,Memory Visibility,我已经看过了,它说明了如何: 在新的内存模型下,当线程A写入易失性 变量V,线程B从V读取 在编写V时A是可见的,现在保证是可见的 B可见 因此,举一个例子: public class Main { static int value = -1; static volatile boolean read; public static void main(String[] args) { Thread a = new Thread(() -> {
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();
}
}
尽管值
(仅读取
)无波动性,线程b是否仍能看到对值
(从-1到1)的更改
如果是这样的话,考虑到为了让另一个线程可见而执行的一系列更改,除了最后一个变量是易失性的之外,更改任何变量是否有任何目的?是的,对
值的更改保证对线程b可见
JLS表示:
- 对易失性变量v的写入(§8.3.1.4)与任何线程对v的所有后续读取同步(其中“后续”是根据同步顺序定义的)
JLS表示:
两个动作可以由“发生在之前”关系排序。如果一个动作发生在另一个动作之前,那么第一个动作对第二个动作可见并在第二个动作之前排序
如果我们有两个动作x和y,我们写hb(x,y)来表示x发生在y之前
- 如果x和y是同一线程的动作,并且x在程序顺序中位于y之前,那么hb(x,y)
- 从一个对象的构造函数的结尾到该对象的终结器(§12.6)的开始,有一个before边
- 如果动作x与后续动作y同步,那么我们还有hb(x,y)
- 如果hb(x,y)和hb(y,z),那么hb(x,z)
项目符号1表示value=1
发生在read=true
之前
项目符号3表示read=true
发生在之前!阅读
子弹1说,!read
发生在值:“+Value
之前项目符号4表示
value=1
发生在值之前:“+value
好的,记住这些规则,你能不能也讨论一下第二个问题(关于使用使变量上次不改变的变量)?@Theenjadev您想让我们推测一下,在某些情况下,是否需要使它们中的一个以上不稳定这里已经有了一个答案:如果最后一个更改的线程始终是另一个线程读取的第一个线程,那么就没有必要使其他线程不稳定。如果你不能做出保证,答案是:视情况而定!