JCIP のセクション 16.3「初期化の安全性」の説明をいくつか読みましたが、まだ明確ではありません。セクションは次のように述べています
「さらに、適切に構築されたオブジェクトの final フィールド (final 配列の要素や final フィールドによって参照される 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 ミリ秒後としましょう)、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が consumer () を呼び出すとき、name、cupsWon、netWorth は null、0、または 0.0 になる可能性がありますか? Container クラスのフィールドは最終的なものではないため、可視性が保証されないため、可能であると考えていました。
b) ただし、セクション 16.3 と「適切に構築されたオブジェクトの final フィールドを介して到達できる変数」に関するビットを読みましたが、これは、コンテナ c のインスタンスが final と宣言されているため、可視性が保証されていることを意味しますか?消費()?
最終的なコンテナ c = 新しいコンテナ("Ted Dibiasi", 10, 1000000);
c) Client クラスの Container への参照を volatile として宣言しても、参照に関連するため、フィールドの可視性の問題は解決されません。