2011-12-21 18 views
5

本のサンプルコードを見直して、次のコード(簡略化された)に遭遇しました。 コードでは、Subscribe(T subscriber)が呼び出されると、スレッドはロックセクションに入ります。 を呼び出し、ロック内のコードがAddToSubscribers(T subscriber)メソッドを呼び出すと、メソッドに別のロックが発生します。なぜこの第二のロックが必要ですか?ロック内部ロックの背後にある根拠?

public abstract class SubscriptionManager<T> where T : class 
{ 
    private static List<T> subscribers; 
    private static void AddToSubscribers(T subscriber) 
    { 
     lock (typeof(SubscriptionManager<T>)) 
     { 
     if (subscribers.Contains(subscriber)) 
      return; 
     subscribers.Add(subscriber); 
     } 
    } 

    public void Subscribe(T subscriber) 
    { 
     lock (typeof(SubscriptionManager<T>)) 
     { 
     AddToSubscribers(subscriber); 
     } 
    } 
} 

答えて

10

この文脈では、そうではありません。しかし、ロックはリエントラントなので、AddToSubscribersの他の呼び出し元が確実にロックを監視するのに役立ちます。実際には、その理由のために私は "Subscribeからそれを取り除き、ただAddToSubscribersにロックをさせる"と言うでしょう。

ただし、 Typeのロックはかなり危険です。フィールドには、より安全になります:

// assuming static is correct 
private static readonly object syncLock = new object(); 

lock(syncLock)subscribersが割り当てられたときに応じて、lock(subscribers)(余分なフィールドはありません)と一緒に離れることもあります。

Iもインスタンス方法は静的状態に追加有するかなり....異常であることに注意すべきです。 IMO Subscribeは、現在のインスタンスとは関係がないため、staticメソッドにする必要があります。

+0

実際、この例はWCFブックから、サブスクリプションマネージャはWCFサービスの基本クラスですクラス。したがって、インスタンスメソッドが必要です。私はまた、あなたが述べたように、Typeのロックは危険であるとMSDNから読んでいますが、コンテキストがWCFであるという事実は何か違いがありますか? – Yeonho

+1

@ダニエルはまったくありません。 –

+0

@Marc "プライベート静的読み取り専用オブジェクトsyncLock =新しいオブジェクト();" - これはすべてのSubscriptionManagerに対して単一のグローバルロックを与えます;元のコードは構築されたタイプごとに1つのロックを持っていると考えています(つまり、別個の「T」ごとに1つ)。 – Joe

4

投稿したコードでは、必要ありません。しかし、もう一度、あなたが投稿したコードは不完全です - 例えば、加入者リストは決して初期化されません。

typeof(SubscriptionManager)をロックするのは良い考えではありません。subscribersフィールドでロックする方が良いでしょうが、サブスクライバーフィールドを初期化する必要があります。

2

おそらく、そのサンプルの近くを読んで、どの本が話しているかを見てください。

この場合、いいえ、2番目のロックは不要です。

注:このサンプルは、公開オブジェクト(タイプ)をロックしているため危険です。通常、特殊なプライベートオブジェクトをロックするので、外部コードは誤って同じオブジェクトをロックすることによってデッドロックを誤って導入することはできません。

1

また、私は一度ネストされたロックを使用しなければならない状況に直面しました。

私の場合は、静的関数であったため、2番目のロックの機能は他の場所から呼び出される可能性があります。ただし、各データメンバーはインスタンスに属し、静的ではないため、必要ではありません。

関連する問題