キャッシュとして使用されるスタティックSystem.Collections.Generic.Dictionary<K, V>
があります。キャッシュ・ミスに私は指定されたキーの値を取得し、キャッシュに保存するためにいくつかの高価な作業を行います。同じキー/値を持つ複数のスレッドから辞書を更新することは安全ですか
private static Dictionary<K, V> _cache = ...
public static V GetValue<K>(K key)
{
V value;
if (!_cache.TryGetValue(key, out value))
{
value = GetExpensiveValue(key);
_cache[key] = value; // Thread-safety issue?
}
return value;
}
これは一般的なパターンです。問題は:複数のスレッドが同時にGetValue()
を呼び出そうとしたときに、これは安全か、失敗する可能性がありますか?
GetExpensiveValue
が与えられたキーに対して常に同じ値を返すと仮定すると、どのスレッドが競合状態に勝つかは実際には気にしません。はい、高価な操作は潜在的に必要以上に1回以上実行されることを意味しますが、これはトレードオフであり、読み取りが書き込みよりも頻繁に行われると幸いです。しかし、実際に何かが辞書の中で間違っていますか?つまり、例外がスローされたり、データが破損することがあります。私はこれをシンプルなコンソールアプリで試してみましたが、問題は見つかりませんでしたが、もちろんそれが常に機能するというわけではありません。
これは安全ではありません。 TryGetValue *自体はスレッドセーフではありません。辞書が別のスレッドによって突然変異されている場合、スパークのシャワーで爆発する可能性があります。 –
良い点マーク。おそらくSystem.Collections.Concurrent.ConcurrentDictionary <>()を使うだけの方がいいだろうか? http://msdn.microsoft.com/en-us/library/dd287191.aspx –