2016-06-02 4 views
2

コードサンプルフィールド値bereadを一度強制的に強制的に同期する方法はありますか? <strong>MyClassの</strong>の

public class MyClass{ 
     private MyObject myObject;   
     private Object lockObject = new Object();   
     MyObjectFactory factory; 

     public MyClass(MyObjectFactory factory){ 
      this.factory = factory; 
     } 

     public MyObject GetObject() 
     { 
      if (myObject == null){ 
       lock(lockObject){ 
        myObject = factory.Create(); 
        //need forcibly sync myObject value beetween all threads here 
       } 
      } 
      return myObject; 
     } 
    } 

インスタンスが複数のスレッドで共有beetwen。私は揮発性のmyObjectを使用することができ、それは書き込みでフィールド値を同期させるだけでなく、私は遅い読み込みを取得します知っている。同期が可能ですmybody値はロック部に1回だけ入力します揮発性

答えて

2

あなたはそれをダブルチェックパターンを実装するように、わずかにあなたのコードを変更する必要があります。

public MyObject GetObject() 
{ 
    if (myObject == null) 
    { 
     lock(lockObject) 
     { 
      if (myObject == null) 
      { 
       myObject = factory.Create(); 
      } 
     } 
    } 
    return myObject; 
} 

コードがしかのx86/x64プロセッサ上で実行されるならば、あなたのようにvolatileキーワードを必要としませんCPUメモリモデルは、他のスレッドがifステートメントまたはifステートメントのいずれかでロックが取得されると、myObjectへの変更が確実に表示されるように強くなります。

また、あなたは、あなたからこれを隠すためにLazyInitializerクラスを使用することができます。

ここ
private MyObject myObject;   
    private Object lockObject;   
    private MyObjectFactory factory; 
    private bool initialized; 

    public MyObject GetObject() 
    { 
     return LazyInitializer.EnsureInitialized(ref myObject, ref initialized, ref lockObject, factory.Create) 
    } 

オブジェクトがすでに作成されているとき、あなただけのブールに揮発性の読み取りのヒットを取りますよ。ロックオブジェクトをまだ作成していない場合は、ロックオブジェクトが割り当てられます。

+0

x86/x64プロセッサは興味深い事実です。私たちのサーバーはx86プロセッサを使用しているので、それは私のための解決策になると思います。しかし、私は理論的な関心を持っています - 一般的に状況を解決することが可能かどうか、プロセッサアーキテクチャについての前提はありませんか? – Frank59

+1

新しい情報でそれは私のための完全な解決です。ありがとう! – Frank59

0

この場合、代理人を使用する必要があります。スレッドは、デリゲートを使用してメインスレッド内のメソッドにアクセスしてデータを渡し、bewスレッドの作成時にjoinを使用しなかったと仮定してすぐにアクションを実行させます。

関連する問題