LUKIYA'S NEVERLAND

春去秋来,花谢花开。


新版雷神中,使用了大量的静态变量作为缓存方式。
 
但是当访问量很大时,经常发生同一时间争抢操作同一静态变量的问题。结果便是出现未处理异常,造成IIS程序池死掉。
 
向Teddy和若水请教后得出解决方案。
 
问题例子(未处理资源争抢情况):
 
定义静态变量:
class Caches{
    public static Dictionary<string, string> Dic_Node = new Dictionary<string, string>();
}
 
使用:
 
if (Caches.Dic_Node.Count == 0)
{
    // 填充Dic_Node 操作
}
 
分析:
 
    此情况中未考虑多线程环境,结果便是访问量如果很大,就会造成资源争抢,同时填充Dic_Node变量。出现异常,提示:“相同的键值已经存在”。
 
解决方案一:
 
lock (Caches.Dic_Node )
{
    if (Caches.Dic_Node.Count == 0)
    {
        // 填充Dic_Node 操作
    }
}
 
原理:
    前面的文章我写过lock的作用,他可以锁定一个资源,规定在同一时间只能有一个线程访问此资源。其他的资源要想访问必须排队等待。使用此代码片段就能够保证资源的独享。但是缺点也是显而易见的,此举会造成访问速度上的损耗,所以有了下面的例子。
 
解决方案二:
 
if (Caches.Dic_Node.Count == 0)
{
    lock (Caches.Dic_Node )
    {
        if (Caches.Dic_Node.Count == 0)
        {
            // 填充Dic_Node 操作
        }
    }
}
 
这个解决方案就比较好了,他充分考虑了性能损耗和资源争抢的情况。但是为什么需要判断两次我还是比较模糊,只大概抓到一点头绪,今天继续请教。