4

ConcurrentDictionary のドキュメントを見ると、次のように書かれています。

複数のスレッドが同時にアクセスできるキーと値のペアのスレッド セーフなコレクションを表します。

これを読むと、ConcurrentDictionary API で任意のメソッドを呼び出すことができ、スレッドセーフになると思います...しかし、これは明示的な実装も含めることを意味していましたが、その保証はありますか?

私の例は、その値が何らかの値である場合に、アトミック操作で ConcurrentDictionary から項目を削除する場合です。

だから私はこれを行うことができます:

var concurrentDictionary = new ConcurrentDictionary<string, string>();
concurrentDictionary.TryAdd("hey", "ho");

((ICollection<KeyValuePair<string, string>>) concurrentDictionary).Remove(new KeyValuePair<string, string>("hey", "ho"));

ソースコードを調べたところ、その操作はアトミックかつスレッドセーフですが、ConcurrentDictionary API にないという事実は、それを使用すべきではないことを意味します...または、コレクションを使用して実行している可能性があります私がそれを使ってはいけないこと。

さらに一歩進んで、次の拡張メソッドを記述できます。

public static boolean TryRemove(this ICollection<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
{
    return collection.Remove(new KeyValuePair<TKey, TValue>(key, value));
}

これは ConcurrentDictionary の Intellisense に表示されます。これは ICollection インターフェイスを実装しており、多くの開発者は何か問題があることさえ知らない可能性があるためです (実際に何か問題があるとしたら?!)。

編集: 「暗黙的に文書化された」とは、ConcurrentDictionary が一連のインターフェイスを実装するということです。ドキュメントには、スレッドセーフであると記載されていますが、そのページにリストされているメソッドのみについては記載されていませんが、インスタンスに対するすべての操作が安全であることを暗示しています。

4

2 に答える 2

0

説明したことを実行しても、 ConcurrentDictionary の原子性が損なわれることはありません。

コンカレント ディクショナリ内のすべてのバケットの不要なロックが発生する可能性があります。(特定の方法でコレクションとしてアクセスすることにより)

これはディクショナリの「同時」部分を強制終了し、通常のディクショナリをロックで囲むよりも効率が悪くなります。

ConcurrentDictionary のすばらしい点は、アトミックであることではなく、ロックを使用して簡単に実行できることです。同時であることです。つまり、複数のスレッドが互いに待機することなく、アトミックに書き込むことができます。

このことをよく理解すると、GetOrAdd、TryRemove、TryUpdate などを使用すると、前の状態が不明な場合でも、状態への明確な移行が可能になるため、その価値が高くなります。

于 2014-08-22T07:26:10.140 に答える
0

これは文書化された動作に関する質問です。一般に、実際に保持するには、文書化された動作にのみ依存できます。その他の動作はいつでも変更できます (実行時、アプリの実行間、フレームワークのパッチ レベル間など)。

ドキュメントでこれが安全であるという参照を見つけることができれば、これを行っても問題ありません。

そうでなければ、私は一般的に非常に慎重になります。一方、ConcurrentDictionaryはコア タイプであり、BCL チームはその作業に極端な互換性基準を適用しています。これが文書化されていなくても、本番アプリでもこれを実行しても問題ありません。彼らは、主要なフレームワークのバージョン間であっても、呼び出し元を壊さないように非常に注意しています。

これらの互換性保証とこれがコア タイプであるため、ソース コードから知識を引き出すことに問題はありません。

于 2014-06-08T13:54:18.327 に答える