У меня есть статический кеш в памяти, который записывается только раз в час ( или дольше ), а читается многими потоков с чрезвычайно высокой скоростью .Общепринятая мудрость подсказывает, что я следую следующему шаблону:
public static class MyCache
{
private static IDictionary<int, string> _cache;
private static ReaderWriterLockSlim _sharedLock;
static MyCache()
{
_cache = new Dictionary<int, string>();
_sharedLock = new ReaderWriterLockSlim();
}
public static string GetData(int key)
{
_sharedLock.EnterReadLock();
try
{
string returnValue;
_cache.TryGetValue(key, out returnValue);
return returnValue;
}
finally
{
_sharedLock.ExitReadLock();
}
}
public static void AddData(int key, string data)
{
_sharedLock.EnterWriteLock();
try
{
if (!_cache.ContainsKey(key))
_cache.Add(key, data);
}
finally
{
_sharedLock.ExitWriteLock();
}
}
}
В качестве упражнения по микрооптимизации, как я могу избавиться от еще большего количества тиков при относительной стоимости общих блокировок чтения ? Время для записи может быть дорогостоящим, так как это случается редко. Мне нужно читать как можно быстрее. Могу ли я просто сбросить блокировку чтения (см. Ниже) и сохранить потокобезопасность в этом сценарии? Или есть версия без блокировки , которую я могу использовать? Я знаком с ограничением памяти, но не знаю, как безопасно применить его в данном случае.
Примечание: я не привязан ни к одному из шаблонов, поэтому любые предложения приветствуются, если конечный результат будет быстрее и в C # 4.x. *
public static class MyCache2
{
private static IDictionary<int, string> _cache;
private static object _fullLock;
static MyCache2()
{
_cache = new Dictionary<int, string>();
_fullLock = new object();
}
public static string GetData(int key)
{
//Note: There is no locking here... Is that ok?
string returnValue;
_cache.TryGetValue(key, out returnValue);
return returnValue;
}
public static void AddData(int key, string data)
{
lock (_fullLock)
{
if (!_cache.ContainsKey(key))
_cache.Add(key, data);
}
}
}