这个简单的缓存类是否需要线程同步...如果我删除了锁_syncLock语句会遇到任何问题?我想我可以删除锁,因为引用应该正确更新吗? ... BUt我认为如果客户端代码迭代GetMyDataStructure方法并且它被替换,那么会发生什么?
编辑:我用TryGetValue样式方法替换了GetMyDataStructure并删除了所有锁定....这应该没问题吗?
public bool TryGetValue(int id, out MyDataStructure myDataStructure)
{
return _cache.TryGetValue(id, out myDataStructure);
}
谢谢!
public sealed class Cache
{
private readonly object _syncLock = new object();
private IDictionary<int, MyDataStructure> _cache;
public Cache()
{
Refresh();
}
public void Refresh()
{
lock (_syncLock)
{
_cache = DAL.GetMyDataStructure();
}
}
public IDictionary<int, MyDataStructure> **GetMyDataStructure**()
{
lock (_syncLock)
{
return _cache;
}
}
}
答案 0 :(得分:1)
由于对引用类型的赋值是原子的(参见C#标准的第5.5节),因此lock
中不需要Refresh
。
至于锁定GetMyDataStructure
,您实际上可能需要这样做 - 原因涵盖here。虽然我不太确定。
答案 1 :(得分:1)
Cache
类实际上只告诉我们一个引用。这不是本身需要同步,因为它是原子的。然而!这实际上取决于调用者将使用字典做。如果他们只阅读,那么它会起作用 - 但是如果他们中的任何一个要添加/删除/交换值那么它就会崩溃。
我很想暴露(而不是字典)一个带有类似索引器的不可变类型 - 所以没有调用者可以通过改变某些东西来破坏聚会。
编辑后;只有TryGetValue
的版本不再使调用者能够破解它,所以应该没问题。
答案 2 :(得分:0)
我认为这是安全的,因为参考分配是原子的(除非存在隐式转换)。
答案 3 :(得分:0)
GetMyDataStructure中的锁几乎没有任何作用......
您最好考虑一下您将使用_cache的旧实例做什么,这些实例可以在您的代码中被设置为静态或其他长生命对象。真的,这将是地狱。不要使用这种方法。