web-dev-qa-db-ja.com

なぜロックオブジェクトは静的でなければならないのですか?

マルチスレッドのロックにプライベートの静的読み取り専用オブジェクトを使用することは非常に一般的です。 privateは、カプセル化を厳しくすることでロックオブジェクトへのエントリポイントを減らし、最も重要なものへのアクセスを減らすことを理解しています。

しかし、なぜ静的なのでしょうか?

private static readonly object Locker = new object();

最後に、フィールドはクラス内でのみ使用され、代わりにこれを使用することもできます:

private readonly object Locker = new object();

コメントはありますか?

更新:

例として、このコードを貼り付けました(単なる例)。これで静的または非静的ロッカーを使用でき、両方とも正常に機能します。以下の答えを考慮して、むしろこのようにロッカーを定義する必要がありますか? (すみません、私は来週インタビューをします、そして、すべての詳細を知る必要があります:)

private readonly object Locker = new object();

そして、ここにコードがあります:

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceA = _service.GetPriceA();
                                   }
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceB = _service.GetPriceB();
                                   }
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();
        }

ありがとう

103
Houman

「マルチスレッドでロックするためにプライベートの静的読み取り専用オブジェクトを使用することは非常に一般的ではありません」-むしろ、ロックを使用するのが一般的です適切な/選択した粒度で。時々それはstaticです。多くの場合、IMOは-ではなく、instanceベースです。

staticロックが表示される主な時間は、グローバルキャッシュ、またはグローバルデータ/シングルトンの遅延ロードです。そして後者では、それを行うより良い方法がありますとにかく

それは本当に依存しています:シナリオでLockerはどのように使用されますか?それはそれ自身静的なものを保護していますか?その場合、ロックは静的でなければなりません。 インスタンスベースの何かを保護している場合、IMOロックはalsoインスタンスベース。

167
Marc Gravell

静的である必要はありません。実際、notである必要があります。

変数は、ロックに使用するメソッドと同じスコープ内に存在する必要があります。メソッドが静的である場合、変数は静的である必要があり、メソッドがインスタンスメソッドである場合、変数はインスタンス変数である必要があります。

静的変数は、インスタンスメソッドをロックするために使用される場合でも機能しますが、ロックしすぎます。同じインスタンスのメソッドだけでなく、すべてのインスタンスのすべてのメソッドをロックします。

79
Guffa

ロックの範囲と有効期間は、ロックする「もの」に依存する/する必要があります。静的ロックは、主に静的なものをロックするために使用されます。

27
Erno de Weerd