ストアストアバリアをコンストラクタに配置する必要がありますか?コンストラクターにStoreStoreバリアーが必要ですか?
ここは例です。最初にglobal_f = f = r = 0
とします。 1つのスレッドAがオブジェクトを作成し、フィールドに割り当て、グローバル変数に代入:
class Foo {
int x;
void Foo(int x) {
this.x = x;
}
}
f = new Foo(42);
global_f = f;
別のスレッドBは、グローバル変数から参照を取得し、そのフィールドを読み取ります。スレッドBはスレッドBからオブジェクト参照を読み出す
r = global_f.x;
仮定すると実行が、どのような値は、それがr
にX
から読み取ることができますか?常に42かどうか?
私はC++ と Javaの動作に興味があります。 r
は、メモリモデルを理解するためには42であることが保証されていません。
オブジェクトのフィールドが適切に初期化されるように、一般的なコンストラクタの最後にストアストアバリアを置くことができます。これは、C++とJavaの両方の落とし穴のようです。少なくともJavaの場合、最終フィールドにはすべて問題ありませんか?これは実際にはそれほど重要ではありません。なぜなら、少なくともx86とAMD64では、ストア・ストア・バリアがNOPであるからです。しかし、ARMやPOWERなどの他のアーキテクチャではそうではありません。
C++のみ:自動的にメモリバリアが追加されることはありません。プログラマの問題です。次のガイドラインが適用されます。_「ルールを使用するための唯一の支払い」_およびマルチスレッドは、コンパイラによる静的解析には複雑すぎます(コンパイラは各コンパイル単位を個別に認識します)。 –
質問したい言語を絞り込む必要があります。 JavaとC++は異なるメモリモデルと言語セマンティクスを持っています。一つは、クラスはC++の値であり、参照はありません。もう1つはJavaの「volatile」がC++のものと大きく違っている –
なぜここでコンストラクタを選ぶべきかわかりません。状況は、 'x'を設定する他のメソッド呼び出しと同じです。 – EJP