1

私はSortedDictionaryスレッドを安全にすることに取り組んでいますが、よくわからないのは、次のように、1つのスレッドでSortedDictionaryに追加する呼び出しを行うことは安全ですか?

dictionary.Add(key, value);

次のように、別のスレッドでこの辞書からアイテムを取得するだけです。

variable = dictionary[key];

これらの場所のいずれにも明示的な列挙がないため、安全に見えますが、それについて確認することは素晴らしいことです.

4

4 に答える 4

1

いいえ。ツリーを変更するものはすべてスレッドセーフではありません。秘訣は、1 つのスレッドで SortedDictionary をいっぱいにしてから、それを不変として扱い、複数のスレッドがそこから読み取れるようにすることです。(ここに記載されているように、SortedDictionary を使用してこれを行うことができます。これについて言及するのは、読み取り時に変更されるコレクション/辞書/マップがどこかにある可能性があるためです。常に確認する必要があります。)

公開された後に変更する必要がある場合は、問題が発生します。書き込むにはロックする必要があり、すべてのリーダーはそのロックを尊重する必要があります。つまり、リーダーもロックする必要があり、リーダーが同時に読み取ることができなくなります。 通常、これを回避する最善の方法は、まったく新しい SortedDictionary を作成し、新しいものが不変になったら、元の参照を新しいものへの参照に置き換えることです。(これを正しく行うには、揮発性の参照が必要です。) リーダーは問題なく辞書をきれいに切り替えます。古い辞書は、最後の読者が読み終えて参照を解放するまで消えません。

(n リーダーと 1 ライターのロックがありますが、ロックはまったく避けたいと考えています。)

(また、列挙している場合、辞書への参照が突然変更される可能性があることに注意してください。これには、(揮発性の) 参照を参照するのではなく、ローカル変数を使用してください。)

Java にはConcurrentSkipListMapがあり、任意の数の同時読み取りと書き込みが可能ですが、.NET にはまだそのようなものはないと思います。そして、もしあれば、とにかく、不変のSortedDictionaryよりも読み取りが遅くなります。

于 2013-07-17T21:04:22.763 に答える