2012-02-23 18 views
4

私はシングルトンでスレッドの安全性についてthis articleを読んでいましたが、私はlockメソッドを理解していないと思っていました。第二版では私はこの間違ったロックをしていますか?

、著者はこのあり:なぜあなたはpadlockオブジェクトを使用するのではなく、ロックでしょう

public sealed class Singleton 
{ 
    private static Singleton instance = null; 

    Singleton() 
    { 
    } 

    public static Singleton Instance 
    { 
     get 
     { 
      lock (instance) 
      { 
       if (instance == null) 
       { 
        instance = new Singleton(); 
       } 
       return instance; 
      } 
     } 
    } 
} 

:私はもっとこのような何かをやっただろうに対し

public sealed class Singleton 
{ 
    private static Singleton instance = null; 
    private static readonly object padlock = new object(); 

    Singleton() 
    { 
    } 

    public static Singleton Instance 
    { 
     get 
     { 
      lock (padlock) 
      { 
       if (instance == null) 
       { 
        instance = new Singleton(); 
       } 
       return instance; 
      } 
     } 
    } 
} 

をロックしたい実際のオブジェクト?

答えて

13

オブジェクトをロックする前に、Instanceプロパティに初めてアクセスしたときに、どのようなことが起こりますか?

(ヒント:lock(null)はバン...行く)別対策として

を、私はほとんど常に「実際のオブジェクト」のロックを避ける - 典型的には、ウェルその参照が曝露される他のコードが存在し得るので、そして、私はそれがどんなものにロックされるのか必ずしも分かっていません。お使いのバージョン仕事をした場合でも、いくつかの外部コードを書いた場合、何が起こる:

// Make sure only one thread is ever in this code... 
lock (Singleton.Instance) 
{ 
    // Do stuff 
} 

今誰-1でもそのコードが実行中のインスタンスを取得することはできません、彼らがブロックされてしまいますので、ゲッターでゲッターのロックは、それを守るためのものではありません。ゲッター内の複数のアクセスに対して防衛することを意味します。

ロックをより詳細に制御できるようになればなるほど、ロックを推測してデッドロックを回避することが容易になります。

私は非常に時折場合は、「通常の」オブジェクトのロックを取る:私は

  • そのクラスの外にその参照を露出していないよ

    • 私はそのタイプ自体は(これは常に意志自信を持っていますもちろん、thisへの参照を持っている)は、それ自体でロックされません。

    (これのすべては、もちろん、あまりにも、thisにロックを回避する理由です...)

    基本的に、私はあなたが任意のオブジェクトをロックすることを可能にするアイデアがで悪い考えだったと思いますJavaでは、それを.NETでコピーするのは悪い動きでした。(

  • +0

    存在しないオブジェクトをロックすることはできません。 –

    +1

    ああ、意味があります。ありがとう!今、もし私が 'instance'が何らかの理由でnullでないことがわかったら、私のメソッドはうまくいくのでしょうか? –

    +1

    ああ...ここに著者: – oleksii

    1

    ロックの場合、オブジェクトの種類は問わず、実際には問題ではなく、単にフラグとして使用され、スレッドは1つしか保持できませんそれは一度に

    もちろんこれをロックパラメータとして持つことは可能ですが、私は主な理由を推測w HYそれはお勧めできませんが、他のクラスはどこか、オブジェクトをロックすると、あなたのクラスのインスタンスを使用することができるということで、他の誰か場合には、デッドロックにつながる可能性があるためthisまたはその他の非プライベートオブジェクト上でそのstrage問題を引き起こす可能性があります

    2

    ロックは危険です同期のためにそのオブジェクトを使用しようとします。

    これはひどくはありません。だからこそ、人々は何年も噛まずにそれをやることができます。しかし、それでもなお可能であり、objectのプライベートインスタンスのコストはおそらく、リスクの実行を正当化するのに十分なほど大きくはありません。

    関連する問題