2

だから、私は持っていますDictionary<KType,VType> Foo

私が持っている1つのスレッドで:

void Thread1() {
  ...
  if (!Foo.TryGetValue(key, out v)) {
    Foo.Add(new VType());
  }
  ...
}

別のFooスレッドがアクセスするのは、TryGetValue.

では、どれくらいロックする必要がありますか?次のようなことはできますか:

void Thread1() {
  ...
  if (!Foo.TryGetValue(key, out v)) {
    lock (syncobj) {
      Foo.Add(new VType());
    }
  }
  ...
}
void Thread2() {
  ...
  lock (syncobj) {
    Foo.TryGetValue(key, out v))
  }
  ...
}

Thread1 はプログラム計算の 90% を占め、TryGetValue何度も呼び出されます。したがって、できれば毎回 lock を呼び出す必要はありません。

4

1 に答える 1

7

a の実行と同時に別のスレッドで更新が発生する可能性がある場合は、lock毎回行う必要があります。TryGetValue

TryGetValue複数のスレッドの呼び出しが互いに干渉しないという点で、それ自体はスレッドセーフです。しかし、他のスレッドが辞書を使って何か他のことをしているときにTryGetValueスレッドが呼び出された場合、破損の可能性があります。Add

そうは言っても、ロックはひどいものではないかもしれません。あなたはそれTryGetValueが「何度も」呼ばれていると言っていますが、どのくらいの頻度で呼ばれているとは言いません。さらに重要なことに、競合が発生する可能性が高いとは言いません。競合していないロックは、最新のハードウェアでは 50 ナノ秒程度のコストがかかるため、大きな出費ではありません。ロックがどのように機能するかを確認するためだけに、ロックを試すことができます。ReaderWriterLockSlimも検討してください。

ConcurrentDictionary読み取り操作はロックフリーの方法で行われますが、これはロックフリーのデータ構造ではないことを理解することが重要です。あなたの状況ではより良いパフォーマンスを発揮するかもしれませんが(おそらくそうなるでしょう)、それは与えられたものではありません.

于 2013-06-05T00:02:21.417 に答える