Недавно я видел несколько проектов на С#, которые используют шаблон с двойной проверкой на Dictionary
. Что-то вроде этого:
private static readonly object _lock = new object();
private static volatile IDictionary<string, object> _cache =
new Dictionary<string, object>();
public static object Create(string key)
{
object val;
if (!_cache.TryGetValue(key, out val))
{
lock (_lock)
{
if (!_cache.TryGetValue(key, out val))
{
val = new object(); // factory construction based on key here.
_cache.Add(key, val);
}
}
}
return val;
}
Этот код неверен, так как Dictionary
может "увеличивать" коллекцию в _cache.Add()
, а _cache.TryGetValue
(вне блокировки) выполняет итерацию по коллекции. Это может быть крайне маловероятным во многих ситуациях, но по-прежнему не так.
Есть ли простая программа, демонстрирующая, что этот код не работает?
Имеет ли смысл включить это в unit test? И если да, то как?