2010-05-26 55 views
3

这个简单的缓存类是否需要线程同步...如果我删除了锁_syncLock语句会遇到任何问题吗?我想我可以删除锁作为参考应正确更新对吗? ...我认为如果客户端代码遍历GetMyDataStructure方法并且被替换,会发生whar吗?这个简单的缓存类是否需要线程同步?

编辑:我已经用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; 
     } 
    } 
} 
+1

您需要回顾一下您提出的问题并选择一个有助于您的答案,它鼓励人们帮助您,因为我们获得了提供最佳答案的声望点。它看起来像一个下方的勾选框,您可以在上面或下面投票。 – 2010-05-26 10:28:56

回答

1

Cache类真的只告诉我们一个单一的参考。那不是本身需要同步,因为它是原子的。然而!这真的取决于打电话给与字典。如果他们只读,那么它会工作 - 但如果他们中的任何人将要添加/删除/交换值,那么它将分崩离析。

我会试图公开(而不是字典)一个类似索引器的不可变类型 - 所以没有调用者可以通过改变某些东西来破坏聚会。


编辑后;只有TryGetValue版本不再使呼叫者可以打破它,所以应该没问题。

0

我认为这将是安全的,因为引用赋值是原子的(除非存在隐式转换)。

1

由于对引用类型的赋值是原子的(请参阅C#标准的5.5节),因此您不需要在Refresh中的lock

至于锁定在GetMyDataStructure,你可能实际上需要 - 原因涵盖here。虽然我不是特别确定。

+0

我已经用TryGetValue样式方法替换了GetMyDataStructure并删除了所有的锁定....这应该没问题吧? ... 以上。谢谢 – DayOne 2010-05-26 10:50:55

0

在GetMyDataStructure锁几乎没做什么...

你最好想想你将可以在你的代码被asiigned静态或其他长期生活的对象_cache的旧实例做什么。这将是地狱,真的。不要使用这种方法。