0

我想这与发生之前的规则有关,但我没有具体的解释......我的问题是,是否保证线程“线程”可以看到 nonFinalField 对“Hello World”的引用?不,我不想让 nonFinalField 成为最终的,以后也不会更新,因为也没有允许它的方法。

希望我们可以用合理的解释来揭开这个例子的神秘面纱。

先感谢您。

亲切的问候,赫尔曼

public class Test2 {

    private String nonFinalField;

    public Test2() {

        nonFinalField="Hello World";
    }

    void startThread() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("nonFinalField: " + nonFinalField);
            }
        });
        thread.start();
    }

    public static void main(String[] args) {
        Test2 test = new Test2();
        test.startThread();
    }
}
4

3 回答 3

2

是的,Thread started instartThread可以保证看到 的值,nonFinalField因为启动线程会在父线程(调用 main 的线程)和子线程(在 中启动的线程)之间建立“发生在之前”的关系startThread

这在17.4.4(第三个项目符号)的语言规范中列出。

于 2013-10-21T13:56:33.190 回答
0

由于在构造对象(因此完全初始化)之前无法调用startThread,因此该线程肯定会看到已初始化的非最终字段。

但是,如果另一个线程在线程运行之前设法查看它,则另一个线程可能会看到未初始化的字段。

请记住,可以通过反射查看私有字段。

于 2013-10-21T13:55:11.293 回答
0

据我了解,它将是可见的。使用 java.util.concurrent 包 javadoc 中的“happens-before”关系规则:

  • 线程中的每个动作都发生在该线程中的每个动作之前,这些动作按程序的顺序出现在后面。
  • 在线程上启动的调用发生在已启动线程中的任何操作之前。

由于happens-before 是可传递的,这意味着'在调用ThreadB.start() 之前ThreadA 中的每个动作都发生在ThreadB 中的每个动作之前'。

因此,如果 ThreadA 是您的主线程,而 ThreadB 是您明确创建的线程,那么在启动第二个线程之前主线程中的事件将是可见的。

于 2013-10-21T14:05:42.820 回答