我试图通过为一些非常中心的函数引入缓存层来从我的数据库服务器卸载工作,这些函数将值插入数据库中的表并检索 id。这是在多线程环境中。
我的第一种方法是:
public class Cache {
private Dictionary<string, Int64> i;
public void Init() { /* init i with values from DB */ }
public Int64 Get(string value)
lock(i) {
Int64 id;
if (cache.i.TryGetValue(value, out id))
return id;
id = /* Insert to DB and retrieve ID */
cache.i[value] = id;
return id;
}
}
这有帮助。然而,线程仍然彼此等待很多。我想减少这个等待时间。我的第一个想法是使用ConcurrentDictionary.GetOrAdd(key, valueFactory)
. 这是行不通的,因为 valueFactory 可以被多次调用。
我已经结束了这种方法:
public class Cache
{
private ConcurrentDictionary<string, Int64> i;
public void Init() { /* init i with values from DB */ }
public Int64 Get(string value)
{
Int64 id;
if (i.TryGetValue(value, out id))
return id;
lock (i)
{
if (i.TryGetValue(value, out id))
return id;
id = /* Insert to DB and retrieve ID */
i.TryAdd(value, id);
return id;
}
}
有没有更好的方法来做到这一点?这甚至是线程安全的吗?