我已经阅读了JCIP对第16.3节“初始化安全”的一些解释,但仍然不清楚。该部分指出
“此外,可以通过正确构造的对象的最终字段(例如最终数组的元素或最终字段引用的 HashMap 的内容)访问的任何变量也保证对其他线程可见。”
因此,如果我有以下可变对象:
public final class Container{
    private String name;
    private int cupsWon;
    private double netWorth;
        public Container( String name, int cupsWon, double netWorth ){
             this.name = name;
             this.cupsWon = cupsWon;
             this.netWorth = netWorth;
        }
    //NO Setters
    //Getters
}
然后,线程 1如下创建它并将 c 传递给Thread2。
final Container c = new Container("Ted Dibiasi", 10, 1000000);
Thread2(不是并发的,让我们说在 1 ms 之后),读取 c 的值,Thread2 是否可能会看到
c.name=null or
c.cupswon=0 or worst of all, 
c.netWorth=0.0?
干杯
更新
我注意到有一些关于类有吸气剂的困惑。我正在更新源代码,希望这会很清楚。谢谢大家看看。
public final class Container{
    private String name;
    private int cupsWon;
    private double netWorth;
    public Container( String name, int cupsWon, double netWorth ){
        this.name = name;
        this.cupsWon = cupsWon;
        this.netWorth = netWorth;
    }
    public final String getName(){
        return name;
    }
    public final int getCupsWon(){
        return cupsWon;
    }
    public final double getNetWorth(){
        return netWorth;
    }
}
//------------
public final class Producer{
    private final Client client;
    public Producer( Client client ){
         this.client = client;
    }
    //Thread1 call produce()   
    public final void produce( ){
        final Container c = new Container("Ted Dibiasi", 10, 1000000);
        client.update( c );
    }
}
//----
public final class Client{
     private Container c;
     //private volatile Container c;       
     public final void update( Container c ){
          this.c = c;
     }
     //Thread2 calls consume().
     public final void consume( ){
          String name = c.getName();
          int cupsWon = c.getCupsWon();
          double netWorth = c.getNetWorth();           
     }
 }
我的问题是:
a) 当Thread2调用 consume() 时,name、cupsWon、netWorth 可以为 null、0 还是 0.0?我的想法是它可以,因为 Container 类中的字段不是最终的,因此没有可见性保证。
b)但是,然后我阅读了第 16.3 节和有关“可以通过正确构造的对象的最终字段到达的变量”的内容,这是否意味着因为容器 c 的实例被声明为最终的,所以我们确实有可见性保证消耗()?
final Container c = new Container("Ted Dibiasi", 10, 1000000);
c) 将 Client 类中对 Container 的引用声明为 volatile 不会解决与引用相关的字段的可见性问题。