pow*_*tte 11 c# multithreading locking
假设我有这个功能(假设我以线程安全的方式访问Cache):
object GetCachedValue(string id)
{
if (!Cache.ContainsKey(id))
{
//long running operation to fetch the value for id
object value = GetTheValueForId(id);
Cache.Add(id, value);
}
return Cache[id];
}
Run Code Online (Sandbox Code Playgroud)
我想阻止两个线程同时运行" 长时间运行"操作同一个值.显然我可以将整个东西包装在一个lock()中,但是整个函数会阻塞而不管值是什么,我希望两个线程能够执行长时间运行操作,只要它们正在寻找不同的id.
是否存在基于值锁定的内置锁定机制,因此一个线程可以在另一个线程完成长时间运行操作时阻塞,因此我不需要执行两次(或N次)?理想情况下,只要在一个线程中执行长时间运行操作,其他线程就不应该为相同的id值执行此操作.
我可以通过将id放在HashSet中然后在操作完成后删除它们来自己滚动,但这看起来像是一个黑客.
我会Lazy<T>在这里使用.下面的代码将锁定缓存,将其Lazy放入缓存并立即返回.长时间运行操作将以线程安全方式执行一次.
new Thread(() => Console.WriteLine("1-" + GetCachedValue("1").Value)).Start();
new Thread(() => Console.WriteLine("2-" + GetCachedValue("1").Value)).Start();
Run Code Online (Sandbox Code Playgroud)
Lazy<object> GetCachedValue(string id)
{
lock (Cache)
{
if (!Cache.ContainsKey(id))
{
Lazy<object> lazy = new Lazy<object>(() =>
{
Console.WriteLine("**Long Running Job**");
Thread.Sleep(3000);
return int.Parse(id);
},
true);
Cache.Add(id, lazy);
Console.WriteLine("added to cache");
}
return Cache[id];
}
}
Run Code Online (Sandbox Code Playgroud)