に読んで、私は実際にA
とB
それらを呼び出す、私は2つのスレッドを持っている配列、1つのスレッドで更新し、別の
を求めているかのより明確な表現を与えるために質問を簡素化。それらはName
というフィールドを持つタイプFoo
のオブジェクトを共有し、タイプFoo[]
のインデックス0
の配列に格納されます。スレッドは常にシステムによって保証されている順序でインデックス0
にアクセスします。したがって、スレッドB
の競合状態がなくなり、スレッドA
の前に取得されます。
注文はこちらです。
// Thread A
array[0].Name = "Jason";
// Thread B
string theName = array[0].Name
私はこの順序がすでに保証され言ったように、値を読み取るスレッドBのためのない方法は、スレッドの前にありません
私は何を確実にしたいことは二つのものです:
- 両方のスレッドがインデックス0で最新のオブジェクトを取得します。
- スレッド
B
は常に.Nameフィールドの最新の値を取得します
volatileとマークするのはオプションではありません。実際のオブジェクトは非常に複雑で、揮発性属性が付加されていないカスタム構造体もあります。
今、1を満たすことは容易である(常に最新のオブジェクトを取得)、あなたは.VolatileReadを行うことができます。
// Thread A
Foo obj = (Foo)Thread.VolatileRead(ref array[0]);
obj.Name = "Jason";
// Thread B
Foo obj = (Foo)Thread.VolatileRead(ref array[0]);
string theName = obj.Name
それとも、メモリバリアを挿入することができます。
// Thread A
array[0].Name = "Jason";
Thread.MemoryBarrier();
// Thread B
Thread.MemoryBarrier();
string theName = array[0].Name
だから私の質問これは、条件2も満たしていますか?私が読んだオブジェクトのフィールドから常に最新の値を取得することができますか?インデックス0
のオブジェクトは変更されていませんが、Name
のオブジェクトが変更されている場合インデックス0
のVolatileRead
またはMemoryBarrier
を実行すると、インデックス0
のオブジェクトのすべてのフィールドも最新の値を取得しますか?
なぜあなたは配列を使用していますか? ['System.Collections.Concurrent'](http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx)名前空間を参照してください。 – Oded
.NET4を使用していません。 Concurrentは、私が知る限り、コレクション自体の内容を保証し、コレクション内のオブジェクトの可能なフィールド/プロパティは保証しません。 – thr
私は揮発性があなたの考え方を保証するとは思わない。 –