2009-03-30 18 views
1

可能であれば、キャッシュからロードされるカスタムオブジェクトを作成するためにファクトリパターンを使用します。 カスタムオブジェクトには静的メンバーや関数はありません。共有インスタンス間のスレッドの安全性(C#)

2つのスレッドがファクトリを呼び出し、両方がキャッシュから同じオブジェクトへの参照を返すと仮定します。

A)Shoulb私が最初にそれをロック:私はクラス内にプライベートインスタンスメンバーを変更したい場合は

を(すなわち、ノーnew演算子、REFにオブジェクトがコレクションから返され、以下答えるために)? b)両方のスレッドに変更が反映されますか?

私は両方の質問についてyesと仮定しますが、同時にスレッドのクラスのインスタンスが異なるように感じます。

私はここで何か基本的なものが必要ですか?なぜ私は私のように感じるのですか?私は、私が思っ感謝を確認している最初のいくつかの答えに続き

===============

私が本当に知りたいのは、オブジェクトがほとんど読み込み専用でない場合、つまり作成後にインスタンスメンバーが1つしか変更できない場合、プロパティを読み込むときにロックを行う必要があるということですその1つの変更可能なインスタンスメンバーの影響を受けませんか?

は再び私は負いませんが、私は、集団のStackOverflowのセカンドオピニオンを評価するために来ている脳は:)

答えて

2

ほとんどのプリミティブ型、文字列とオブジェクト参照の読み書きは、アトミック(非揮発性のlongとdoubleを除くすべて)です。つまり、単にフィールドまたは他の変数を単独で読み書きする場合は、ロックは必要ありません。あなたは今までにこのようなコードを参照してください(と私はあなたが意志guaranteee)のであれば、あなたは喜んで不要と高価なロック取り除くことができます、しかし、あなたが値を変更したい場合は、

public SomeClass SomeProperty 
{ 
    get 
    { 
     lock (someLock) 
     { 
      return someField; 
     } 
    } 

    set 
    { 
     lock (someLock) 
     { 
      someField = value; 
     } 
    } 
} 

を1で、それを増やしますたとえば、関連する複数の変数を読み込みたい場合は、賢明な結果を得たい場合はロックする必要があります。

ハッシュテーブルとディクショナリは、あらゆる種類のロックを必要とせずに複数の並行リーダをサポートしていることにも注意してください。

0

new演算子やコンストラクタがオブジェクトの上に二回呼ば取得されている場合は、あなたが持っている信頼同じクラスの2つのインスタンス

1

スレッドにオブジェクトのインスタンスが異なると想定していますが、これは間違っています。スレッドは同じオブジェクトを指しています。したがって、プロパティアクセスやメソッド呼び出しなど、複数のスレッドからアクセスできるメンバーへのアクセスを同期させる必要があります。

1

これは同じオブジェクトで、質問に対する回答は次のとおりです。はいはい。

2つのインスタンスがあることをどのように確認しますか?

1

はい、プライベートメンバーを設定する前にロックする必要があります。これは両方のスレッドに反映されます(同じオブジェクトなので)。

ただし、ロックとスレッドを処理する方法を検討するのに時間がかかることがあります。

工場がオブジェクトを作成してコレクションに追加している場合は、そのオブジェクトを作成するためにルーチンの周りに何らかの形のロックが必要です。それ以外の場合は、2つのスレッドがオブジェクトを作成する前に同時に要求し、2つのインスタンスを作成する可能性があります。

また、プライベートメンバーを直接設定することはお勧めしません。ロックされたクラスインスタンス内に単一のオブジェクトを配置し、アクセサ(メソッドまたはプロパティ)を使用することをお勧めします。その同期オブジェクトをロックしてフィールドを設定します。

2つのインスタンスを「信頼する」としては、デバッガをチェックインするために何かを行うことができます。参照の平等のためのチェックを追加するか、一時的にGUIDを作成時に設定されたクラスに追加してください。同じようになっていることを簡単に確認できます。

0

プライベートメンバーを変更した結果を確認するには、両方のスレッドが必要ですか?または、両方のスレッドがオブジェクトを取得しても問題ありませんが、一方のスレッドがプライベートメンバーを変更したとき、もう一方のスレッドはその変更を認識しません。

これは私が尋ねる理由です:あなたの工場では、オブジェクトをキャッシュから取り出し、それを返す前に複製またはコピーすることができます。その結果、各スレッドはクラスの独自のコピーを持ち、そのコピーは要求した時点でキャッシュされたオブジェクトにあった状態になります。スレッドごとにコピーを作成しているので、2つのスレッドはまったく同じインスタンスを共有しません。

あなたの要件に合っていれば、オブジェクトをロックする必要がなくなります(ただし、現在のケースでは必要ですが、ファクトリメソッド自体に同期が必要です)。

「クローン」という概念には注意してください。オブジェクトのグラフがあり、浅いクローンしか作成していない場合は、スレッド間で共有されている参照を参照して、再度同期する必要があります。スレッドごとに1つのコピーというこのアイデアは、オブジェクトが他のオブジェクトへの参照をほとんど持たない非常に単純なオブジェクトである場合に最も適しています。

関連する問題