防止两个线程进入一个代码块具有相同值 [英] Prevent two threads entering a code block with the same value
问题描述
说我有这个功能(假设我访问缓存的线程的方式):
Say I have this function (assume I'm accessing Cache in a threadsafe way):
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];
}
我想阻止两个线程运行的长期运行的操作的在同一时间的为相同的值。很显然,我可以包住整个事情的锁(),但随后的整体功能会阻止不管价值,我想两个线程可以,只要他们正在寻找不同的ID的执行长时间运行的操作。
I want to prevent two threads from running the "long running operation" at the same time for the same value. Obviously I can wrap the whole thing in a lock(), but then the whole function would block regardless of value and I want two threads to be able to perform the long running operation as long as they're looking for different id's.
有一个内置的锁定机制来锁定基于一个值,而其他线程完成的长时间运行的操作的,所以我有一个线程可以阻止不需要做两次(或N倍)?理想的情况是,只要的长时间运行的操作的正在在一个线程中进行的,没有其他线程应该能够做到这一点对相同的id值。
Is there a built-in locking mechanism to lock based on a value so one thread can block while the other thread completes the long running operation so I don't need to do it twice (or N times)? Ideally as long as the long running operation is being performed in one thread, no other thread should be able to do it for the same id value.
我可以投入的HashSet的ID和那么一旦操作完成,消除他们推出自己的,但是这似乎是一个黑客。
I could roll my own by putting the id's in a HashSet and then removing them once the operation completes, but that seems like a hack.
推荐答案
我会用 懒< T>
在这里。下面的代码将锁定缓存,把懒
到缓存中,并立即返回。的长期运行的操作的将曾经在一个线程安全的方式执行。
I would use Lazy<T>
here. Below code will lock the cache, put the Lazy
into the cache and return immediately. Long-running-operation will be executed once in a thread safe manner.
new Thread(() => Console.WriteLine("1-" + GetCachedValue("1").Value)).Start();
new Thread(() => Console.WriteLine("2-" + GetCachedValue("1").Value)).Start();
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];
}
}
这篇关于防止两个线程进入一个代码块具有相同值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!