1

在我的 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();
        }
    }
4

1 回答 1

0

这里肯定有竞争条件。如果一个线程刚刚退出lock并且此时另一个线程调用(并完成)Refresh,则第一个线程null将从CodeNames. 如果CodeNames是从内部读取GetName,这将立即导致一个NullReferenceException.

为防止这种情况,您需要Refresh使用 a进行保护lock(sync)或重写CodeNames如下:

lock (sync)
{
    if (cachedCodeNames == null)
    {
        var codeNames = WebServiceManager.GetCodeNameCache();
        cachedCodeNames = codeNames;
        return codeNames;
    }
}

当然,在这种情况下,你应该应用大量的评论来明确这个看似毫无意义的仪式实际上是一个重要的特征。

于 2013-02-25T12:05:28.483 回答