1. Qiita
  2. 投稿
  3. C#

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

  • 5
    いいね
  • 6
    コメント
この記事は最終更新日から1年以上が経過しています。

よくある初期化用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用のオブジェクトであることが型を見ればわかる

地味に便利