0

してください:私はセッションファクトリの実装は、シングルトンのようにする必要が静的な揮発性ISessionFactory

public sealed class MySessionFactory 
{ 
    private static volatile MySessionFactory _instance; 
    private ISessionFactory _sessionFactory; 
    private static volatile object _locker = new object(); 

    private MySessionFactory() 
    { 

    } 

    public MySessionFactory Intance 
    { 
     get 
     { 
      if (_instance != null) 
       return _instance; 

      lock (_locker) 
      { 
       if (_sessionFactory == null) 
       { 
        _instance = new MySessionFactory(); 
       } 
      } 

      return _instance; 
     } 
    } 

    public ISession OpenSession() 
    { 
     if (_sessionFactory != null) 
      return _sessionFactory.OpenSession(); 

     lock (_locker) 
     { 
      if (_sessionFactory == null) 
      { 
       var cfg = FluentNHibernate.Cfg.Fluently.Configure() 
        .Database(FluentNHibernate.Cfg.Db.PostgreSQLConfiguration.Standard.ConnectionString("connectionString").UseReflectionOptimizer()) 
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsAssembly>()); 
       _sessionFactory = cfg.BuildSessionFactory(); 

      } 
     } 

     return _sessionFactory.OpenSession(); 
    } 
} 

iは静的変数_INSTANCEの揮発性を削除した場合、私はこの変更にいくつかの利点を得るのだろうか?またはこれは良い練習パターンですか?

+0

Lazy を使用すると、よりクリーンなコードIMHOで同じ目標を達成できます。 –

答えて

1

_instanceフィールドからvolatileを削除するだけで、コードはスレッドセーフではなくなります。

あなたが本当にあなたの_INSTANCEフィールドから揮発除去することができ、「有名な」ダブルチェックロック手法を維持したいが、その後、あなたは次のように見えるように割り当てを変更する必要がある場合:

var tmp = new MySessionFactory(); 
Volatile.Write(ref _instance, tmp); 

これは与えます_instanceフィールドはもはや揮発性ではないので、すべての読み込みが揮発性ではない(いくつかのパフォーマンスの向上)ため、いくつかの利点があります。しかし、コードがまだスレッドセーフであることを保証する揮発性の割り当てがあります。

私の個人的な意見 - ダブルチェックのロック技術を使用しないでください。あなたが本当に遅延初期化を必要とするなら、Lazyクラスを使用してください。あなたは100%の遅延初期化が必要ない場合はちょうどこのようにそれを書く:

private static readonly MySessionFactory _instance = new MySessionFactory(); 

この初期化は、最初のタイムコードは、クラスのメンバーにアクセスしようと自動的に呼び出され、静的クラスのコンストラクタによって呼び出されます。 CLRコンストラクターでは、スレッドセーフであるため、この場合の並行性については心配する必要はありません。あなたのケースでは、MySessionFactory _instanceに関係しないそのクラスのメンバを持っていないので、このソリューションはダブルチェックロックのように怠惰な動作をします。

この詳細については、「The Famous Double-Check Locking Technique」という、Jeffrey Richtersの書籍CLR via C#の全章を参照してください。良い読み方;)

関連する問題