我有一个静态的内存缓存,每小时(甚至更长时间)只写入一次,并且被许多线程以极高的速率读取。传统智慧建议我遵循以下模式:
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);
}
}
}
GetData()
函数中的代码并不知道锁的存在,因此它不会对其做出任何反应。 - svick