在多线程环境中读取值

2024-02-01

我正在浏览有关线程和锁的 JLS 文档http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5 http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5 .

class FinalFieldExample { 
final int x;
int y; 
static FinalFieldExample f;

public FinalFieldExample() {
    x = 3; 
    y = 4; 
} 

static void writer() {
    f = new FinalFieldExample();
} 

static void reader() {
    if (f != null) {
        int i = f.x;  // guaranteed to see 3  
        int j = f.y;  // could see 0
    } 
} 
}

我对本节中提到的关于如何将 f.y 视为零的上述示例(例如,17.5-1)感到困惑。 读取器线程要么将对象 f 读取为 null,在这种情况下它将不执行任何操作,要么将读取带有某些引用的对象 f。如果对象 f 有引用,则即使多个写入线程正在运行,构造函数也必须完成其执行,以便可以将引用分配给 f,并且如果构造函数已执行,则 f.y 应视为 4。

在什么条件下f.y =0 是可能的?

Thanks


在什么条件下f.y =0 是可能的?

Java 内存模型允许 JIT 编译器重新排序初始化非最终的 fields outside构造函数。这x字段是最终字段,因此必须由 JVM 初始化,但是y不是最终的。所以有可能是FinalFieldExample已分配并设置为static FinalFieldExample f但初始化的y字段尚未完成。

引用17.5-1:

因为 writer 方法在对象的构造函数完成后写入 f,所以 reader 方法将保证看到 f.x 的正确初始化值:它将读取值 3。但是,f.y 不是最终的;因此,不能保证 reader 方法看到它的值 4。

Because f.y不是最终的,不能保证在构造函数完成时它已经被设置并且static f被安排了。所以就产生了竞争条件reader可能会看到y3 或 0 取决于这场比赛。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在多线程环境中读取值 的相关文章

随机推荐