LoginSignup
5
8

More than 5 years have passed since last update.

初期化用lockステートメントをラップする

Posted at

よくある初期化用lock

private static object thisLock = new object();
private static SomeObj some;
public void Hoge()
{
    // まだ作られてなければ作る
    if (some == null)
    {
        lock (thisLock)
        {
            if (some == null)
            {
                some = CreateSome();
            }
        }
    }
    // 以降の処理
}

気になる

  • ネスト深い
  • objectの用途を名前で表明するしかない

ラップするクラスを作ってみる

public class ObjectForLock
{
   /// <summary>
   /// 指定したconditionがtrueを返す時自分自身のlockを取得し再度conditionがtrueを返した時指定したactionを実行します
   /// </summary>
   /// <param name="condition"></param>
   /// <param name="action"></param>
   public void IsolateAction(Func<bool> condition, Action action)
   {
       if (condition() == false) return;

       lock (this)
       {
           if (condition() == false) return;

           action.Invoke();
       }
   }
}

先ほどの例を置き換えてみる

private static ObjectForLock thisLock = new ObjectForLock();
private static SomeObj some;
public void Hoge()
{
    // まだ作られてなければ作る
    thisLock.IsolateAction(
        () => some == null,
        () => { some = CreateSome(); });

    // 以降の処理
}
  • ネスト無い
  • lock用のオブジェクトであることが型を見ればわかる

地味に便利

5
8
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8