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

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

作者:互联网

我看过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();
    }
}

尽管价值没有波动(仅读取),但是对于线程b是否可以看到对值的变化(从-1到1)?

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

解决方法:

是的,保证线程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).

Bullet 1表示值= 1发生 – 在read = true之前.
Bullet 3说read = true发生在之前!读取.
Bullet 1表示!在“Value:”值之前读取.
Bullet 4表示value = 1发生在“Value:”值之前.

标签:java,multithreading,volatile,java-memory-model,memory-visibility
来源: https://codeday.me/bug/20190607/1194131.html