【发布时间】:2014-07-23 19:49:45
【问题描述】:
我正在尝试通过为一些非常核心的函数引入缓存层来从我的数据库服务器卸载工作,这些函数将值插入数据库中的表并检索 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;
}
}
有没有更好的方法来做到这一点?这甚至是线程安全的吗?
【问题讨论】:
-
我不会锁定您尝试修改的资源。
-
@DanielA.White 为什么不呢?这是一个非常好的做法。
-
@Servy 你不知道 .net 框架是否可以锁定该引用。
-
@DanielA.White 我希望
ConcurrentDictionary的定义遵循您链接的文章中的建议,并且不会自我锁定,因为 MS 知道这样做是个坏主意所以。粗略检查一下它的定义让我相信它不会像预期的那样自我锁定。
标签: c# database multithreading concurrency concurrentdictionary