如果线程B希望看到线程A发生的变化,那么最后的变化只能是一个易变量而不是全部吗?

Mar*_*hac 4 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(() -> {
            value = 1;
            read = true;
        });

        Thread b = new Thread(() -> {
            while (!read);

            System.out.println("Value: " + value);
        });

        a.start();
        b.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

value尽管value(仅read)的非波动性,是否保证线程b可以看到(从-1到1)的变化?

如果是这样,给定了一堆为了对另一个线程可见而进行的更改,是否有任何目的使得任何变量发生变化而不是最后一个变量?

And*_*eas 5

是的,value保证线程b可以看到更改.

JLS 17.4.4.同步订单说:

  • 对易失性变量v(第8.3.1.4节)的写入与任何线程对v的所有后续读取同步(其中"后续"根据同步顺序定义).

JLS 17.4.5.发生前 - 订单说:

可以通过先发生关系来排序两个动作.如果一个动作发生在另一个动作之前,则第一个动作第二个动作之前可见并在第二个之前被命

如果我们有两个动作xy,我们写hb(x,y)来表示x发生在y之前.

  • 如果xy是同一个线程的动作,并且x在程序顺序中出现在y之前,那么hb(x,y).

  • 从对象的构造函数的末尾到该对象的终结器(第12.6节)的开始有一个发生前的边缘.

  • 如果动作x与后续动作y 同步,那么我们也有hb(x,y).

  • 如果是hb(x,y)hb(y,z),那么hb(x,z).

Bullet 1说value = 1 发生在之前 read = true.
子弹3说read = true 发生在此之前 !read.
Bullet 1说!read 发生在之前 "Value: " + value.
Bullet 4说value = 1 发生在此之前 "Value: " + value.

  • @TheeNinjaDev您是否希望我们推测是否可能存在某些情况需要使其中不止一个"易变"?---你已经在这里得到了一个答案:如果最后一个被改变的是第一个被另一个线程读取的,那么就没有必要让其他线程变得易变.如果你不能做出这样的保证,答案是:这取决于! (3认同)