在我的ASP.NET Web应用程序中,对页面的所有请求都访问此公共静态缓存类。 (所以它必须是线程安全的)
通过调用Cache类的Refresh方法来刷新此缓存是否安全,如下所示。 或者它导致同步问题?
static class Cache
{
static Dictionary<string, string> cachedCodeNames;
static readonly object sync = new object();
public static string GetName(string code)
{
return CodeNames[code];
}
public static void Refresh()
{
cachedCodeNames = null;
}
static Dictionary<string, string> CodeNames
{
get
{
if (cachedCodeNames == null)
{
lock (sync)
{
if (cachedCodeNames == null)
{
cachedCodeNames = WebServiceManager.GetCodeNameCache();
}
}
}
return cachedCodeNames;
}
}
}
static class WebServiceManager
{
internal static Dictionary<string, string> GetCodeNameCache()
{
throw new NotImplementedException();
}
}
答案 0 :(得分:0)
这里肯定存在竞争条件。如果一个线程刚刚退出lock
并且此时另一个线程调用(并完成)Refresh
,则第一个线程将从null
返回CodeNames
。如果从CodeNames
内部读取GetName
,则会立即生成NullReferenceException
。
为防止出现这种情况,您需要使用Refresh
保护lock(sync)
或像这样重写CodeNames
:
lock (sync)
{
if (cachedCodeNames == null)
{
var codeNames = WebServiceManager.GetCodeNameCache();
cachedCodeNames = codeNames;
return codeNames;
}
}
当然,在这种情况下,你应该申请大量的评论,以明确这个看似毫无意义的仪式实际上是一个重要的特征。