当前位置:  开发笔记 > 编程语言 > 正文

为什么发布最终字段安全?

如何解决《为什么发布最终字段安全?》经验,为你挑选了1个好方法。

我目前正在阅读Brian Goetz的Java Concurrency in Practice.在第51页.在其中一个脚注中,他说:

虽然它可能似乎在构造函数中设置字段的值写入这些字段中的第一个值,因此不存在"老"值看作为过时的值,子类的构造函数运行之前Object构造函数首先写入默认值到所有领域.因此,可以将字段的默认值视为陈旧值.

所以,最终领域的概念现在还不清楚.考虑样本类:

public class MyClass{
    private final MyImmutableClass mic;

    public MyClass(){
        mic = MyImmutableClass.empty();
    }
}

根据上面的脚注,mic字段被分配两次,一次由Object构造函数指定,一次由构造MyClass函数本身指定.现在,假设我们MyClass不安全地发布了一个对象(例如通过public字段):

public final MyClass mc;

谁保证mc一致状态下的任何线程都能始终观察到?为什么有些线程不会意外地观察到默认值?

据我所知,该final字段本身仅保证在对象构造之后不能分配引用.如果我们宣布mc挥发性,那将是明确的.读取该字段的任何线程都应该直接从内存中读取它.禁止从缓存中读取它.

UPD:出版示例:

public static void main(String[] args){
    class MyRunnable implements Runnable(){
        private SomeClass sc;
        public MyRunnable(SomeClass sc){
            this.sc = sc;
        }
        public void run(){
            //do some with sc
        }
    }
    SomeClass sc = getInitialized();
    ExecutorService es = Executors.newFixedThreadPool(10);
    MyRunnable mr = new MyRunnable(sc);
    //submiting mr to es 10 times
    es.awaitTemination();
    es.shutdown();
}

private static SomeClass getInitialized(){
    SomeClass sc = new SomeClass();
    sc. initialize();
    return sc;
}
public class SomeClass
    public MyClass mc;

    public void initialize(){
        mc = new MyClass();
    }
}

一个SomeClass实例将在多个线程中发布.某些线程可以观察到该mic字段的默认值吗?



1> Eran..:

mc在您的示例中是一个实例变量.这意味着您必须拥有一个完全初始化的类实例,mc以便访问mc某些实例的任何代码都不会抛出NullPointerException.因此,mc肯定会在访问时初始化.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有