public class Test
{
private object syncRoot = new object(); private volatile Dictionary<int, Dict<int, int>> _userIds; /// <summary>
/// 索引属性:字典对象
/// </summary>
public Dict<int, int> this[int id]
{
get
{
// 检查有无初始化对象
if (_userIds == null)
_userIds = new Dictionary<int, Dict<int, int>>(); // 如果字典中没有则从数据库载入对象
if (!_userIds.ContainsKey(id))
{
lock (syncRoot)
{
// 锁住后再次确认是否没有对应的分类字典
if (!_userIds.ContainsKey(id))
{
_userIds[id] = Offers.GetUserOfferIds(this.UserID, 2, id);
}
}
} return _userIds[id];
} set
{
// 先检查对应的缓存是否存在?
if (_userIds!=null && _userIds.ContainsKey(id))
{
lock (syncRoot)
{
_userIds.Remove(id);
}
}
}
} ...
}
{
lock (syncRoot)
{
...}
}
set
{
lock (syncRoot)
{
...
}
lock应该紧挨属性访问器
// 检查有无初始化对象
if (_userIds == null)
_userIds = new Dictionary<int, Dict<int, int>>();
感觉这段有问题
虽然_userIds 用volatile 修饰,但依赖其旧值无法保证其线程安全。
在执行userIds = new Dictionary<int, Dict<int, int>>();
之前,有可能两个线程同时通过 if (_userIds == null)
。可能会有两次new。