我有一個用於值緩存功能的通用基類。通用基類中的靜態對象的緩存鎖定
public abstract class CachedValueProviderBase<T> : ICachedValueProvider<T> where T : class
{
private Cache Cache { set; get; }
protected string CacheKey { get; set; }
protected int CacheSpanInMinutes { get; set; }
private static readonly object _cacheLock = new object();
public T Values
{
get
{
T value = Cache[CacheKey] as T;
if (value == null)
{
lock (_cacheLock)
{
value = Cache[CacheKey] as T;
if (value == null)
{
value = InitializeCache();
}
}
}
return value;
}
}
protected CachedValueProviderBase()
{
Cache = HttpRuntime.Cache;
CacheSpanInMinutes = 15;
}
public T CacheValue(T value)
{
if (value != null)
{
lock (_cacheLock)
{
Cache.Insert(CacheKey, value, null, DateTime.UtcNow.AddMinutes(CacheSpanInMinutes),
Cache.NoSlidingExpiration);
}
}
return value;
}
private T InitializeCache()
{
T value = Initialize();
CacheValue(value);
return value;
}
protected abstract T Initialize();
}
我有幾個類使用這個基類,只要T是不同的就好了。當兩個子類使用相同的T,例如字符串時,它們共享相同的緩存鎖定對象。在基類中實現邏輯的最好方法是什麼,但仍然給每個子類自己的緩存鎖對象?
更新 建議下面我已經更新了我的課餘:
public abstract class CachedValueProviderBase<T> : ICachedValueProvider<T> where T : class
{
private Cache Cache { set; get; }
protected string CacheKey { get; set; }
protected int CacheSpanInMinutes { get; set; }
private object _cacheLock = new object();
public T Values
{
get
{
T value = Cache[CacheKey] as T;
if (value == null)
{
lock (_cacheLock)
{
value = Cache[CacheKey] as T;
if (value == null)
{
value = InitializeCache();
}
}
}
return value;
}
}
protected CachedValueProviderBase()
{
Cache = HttpRuntime.Cache;
CacheSpanInMinutes = 15;
}
public T CacheValue(T value)
{
if (value != null)
{
Cache.Insert(CacheKey, value, null, DateTime.UtcNow.AddMinutes(CacheSpanInMinutes),
Cache.NoSlidingExpiration);
}
return value;
}
private T InitializeCache()
{
T value = Initialize();
CacheValue(value);
return value;
}
protected abstract T Initialize();
}
}
我的子類現在單身,所以我可以擺脫靜態cachelock對象使其成爲一個實例變量。
這是運行在網絡服務器上,所以我仍然必須鎖定多個線程的緩存。除去靜態時,可能會有多個線程初始化緩存。 – b3n
然後你應該考慮使用[singleton pattern](http://en.wikipedia。org/wiki/Singleton_pattern),以便您擁有單個緩存,而不管訪問它的線程如何,同時爲每個緩存實例保留唯一的緩存鎖定。 –
@ b3n如果您使用.net 4.0,則可以使用'Lazy'進行線程安全的ininitalization。無論如何,實例方法的靜態鎖是**糟糕的事情。 –
undefined