我正在尝试实施以下方案,无法提出解决方案。
在我的Web服务中,我根据会话ID缓存对象(包含静态数据)。收到请求后,它会检查缓存是否包含会话ID的任何密钥。
现在,在此服务中启用了多线程,并且当多个请求(具有相同的会话ID)被发送到服务时,所有这些请求都试图将数据加载到缓存中,因为它们最初都没有找到该密钥。
问题是:我想停止所有其他线程,直到第一个线程将静态数据加载到缓存中,并且一旦第一个线程完成将数据加载到缓存中,其他线程应该使用该缓存而不是尝试再次加载。 / p>
看起来微不足道,但不知何故无法想到任何可以解决这个问题的多线程功能。
我的代码如下所示:
somemethod()
{
if(cache.Contains(someKey)
{
// use cache and do further processing
}
else
{
cache.add(someKey)
}
}
答案 0 :(得分:0)
您可以尝试以下逻辑 1)Thread1 for come并发现该对象不存在于缓存中 2)在此会话Id的缓存中放置一个等待命令对象。该对象告诉任何其他线程等待进一步通知。 3)Thread1从DB中获取数据并将其放回缓存中。 4)Thread1通知其他线程他们可以继续,因为数据现在可用。
答案 1 :(得分:0)
经典补救措施再次竞争条件是相互排斥。锁定是提供此类功能的最简单的解决方案。
public class Cache
{
private object _locker = new object();
private SessionDataCollection _cache;
public SessionData Get(SessionId id)
{
lock (_locker)
{
if (!Contains(id))
Fetch(id);
return Retrieve(id);
}
}
private bool Contains(SessionId id)
{
//check if present in _cache
}
private void Fetch(SessionId id)
{
//get from db and store in _cache
}
private SessionData Retrieve(SessionId id)
{
//retrvieve from _cache
}
}