首页 > 解决方案 > Java 并发 - volatile 关键字的影响能有多远

问题描述

一个常见的例子解释了关键字的功能volatile可以是这样的(引用自此处):

class VolatileExample {
    int x = 0;
    volatile boolean v = false;
    public void writer() {
        x = 42;
        v = true;
    }
    public void reader() {
        if (v == true) {
            //uses x - guaranteed to see 42.
        }
    }
}

由于v是易失性的,写入操作v将是“直写”,因此其他线程可以看到。更重要的 x是,受vto 的影响也表现得像 volatile ,因为x在上面分配了。

所以我的问题是volatile可以在多大程度上影响之前的操作?

影响是否仅限于分配了 volatile 属性的功能?所以在以下情况下,x遗嘱不会有“直写”的行为:

public void foo() {
    x = 42;
}

public void writer() {
    foo();
    v = true;
}

还是影响不会被限制,可以传播到这个线程之前的所有操作?但考虑到以下情况,这似乎有点不可能:

private void foo() {
    x = 42; // x will be written through
}

private void fooWrapper() {
    foo();
}

private void writer() {
    fooWrapper();
    v = true;
}

// invoke this! 
public void writerWrapper() {
    y = 0; // y will be written through
    writer();
}

标签: javaconcurrencyvolatile

解决方案


它建立了“之前发生过”的关系,因此在该线程中,在 volatile 写入之前发生的任何事情对其他线程都是可见的。在您的最后一个示例中,即使涉及多个函数,它们都在同一个线程中按顺序执行,并且在 volatile 写入之后,之前的所有写入都是可见的。


推荐阅读