java - 在哪些架构/操作系统中,其他线程可以在构造函数调用后看到默认的非最终字段值?

标签 java multithreading constructor cpu-architecture memory-visibility

我正在尝试在非最终字段的对象初始化不足的情况下重现内存可见性问题(JLS 17.5 Final Field SemanticsFinalFieldExample 类示例)。它指出“但是,f.y 不是最终的;因此不能保证 reader() 方法看到它的值 4”

我试过这段代码:

public class ReorderingTest2 {


    public static void main(String[] args) {
        for (int i = 0; i < 2500; i++) {
            new Thread(new Reader(i)).start();
            new Thread(new Writer(i)).start();
        }
    }

    static class Reader implements Runnable {
        private String name;

        Reader(int i) {
            this.name = "reader" + i;
        }

        @Override
        public void run() {
            //System.out.println(name + " started");
            while (true) {
                FinalFieldExample.reader(name);
            }
        }
    }

    static class Writer implements Runnable {
        private String name;

        Writer(int i) {
            this.name = "writer" + i;
        }

        @Override
        public void run() {
            //System.out.println(name + " started");
            while (true) {
                FinalFieldExample.writer();
            }
        }
    }

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

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

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

        static void reader(String name) {
            if (f != null) {
                int i = f.x;
                int j = f.y;
                if (i != 3 || j != 4) {
                    System.out.printf("reader %s sees it!%n", name);
                }
            }
        }
    }

}

previous my similar topic - 我已经在装有 Windows 的不同 PC(从 2 核到 8 核)上尝试过,甚至在我们的服务器端 Solaris 32 核心盒上尝试过 - 我无法重现它:f.x 和 f.y - 总是已经正确初始化。

对于 Intel/x86/x64 架构为 I got the answer - 他们有很多 default memery guarantees这可以防止此类构造函数逻辑重新排序。 Solaris/sparc 似乎也是如此?

那么在什么架构/操作系统中可以重现这种重新排序?

最佳答案

阿尔法。 Paul E. McKenney 的书 Is Parallel Programming Hard, And, If So, What Can You Do About It?有一章解释了最重要平台的内存模型。

关于java - 在哪些架构/操作系统中,其他线程可以在构造函数调用后看到默认的非最终字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6294790/

相关文章:

Java 文件光标

c++ - 类内部的Boost Thread无法访问成员变量

multithreading - 与 FireMonkey 并行的多个 REST 请求

c++ - 构造函数在错误的时间调用

junit - jmockit 模拟构造函数不返回预期值

c++ - 当一个结构有 c-tor 时,为什么我不能静态初始化它?

java - Java中的copy方法、equals方法和空数据的问题

java - androidx.security 依赖问题

java - 为什么switch on String会编译成两个switch

c# - 多线程更新主窗体