【发布时间】:2012-04-23 19:43:21
【问题描述】:
我有一个由多个后台线程访问以更新/读取的列表。更新操作包括插入和删除。
为了在不出现同步问题的情况下同时执行此操作,我在类中的私有只读对象上使用了锁。
为了最大程度地减少读取数据时锁定列表所需的时间,我对其进行深度克隆并返回深度克隆并解锁字典以进行插入/删除更新。
因此,每次读取列表都会增加我的服务的内存消耗。
需要注意的一点是,插入/删除是包含列表的类的内部。但该读物是供公众阅读的。
我的问题是:
有什么办法,我可以避免克隆列表并仍然使用读/写锁同时使用它进行读取?
public class ServiceCache
{
private static List<Users> activeUsers;
private static readonly object lockObject = new object();
private static ServiceCache instance = new ServiceCache();
public static ServiceCache Instance
{
get
{
return instance;
}
}
private void AddUser(User newUser)
{
lock (lockObject)
{
//... add user logic
}
}
private void RemoveUser(User currentUser)
{
lock (lockObject)
{
//... remove user logic
}
}
public List<Users> ActiveUsers
{
get
{
lock (lockObject)
{
//The cache returns deep copies of the users it holds, not links to the actual data.
return activeUsers.Select(au => au.DeepCopy()).ToList();
}
}
}
}
【问题讨论】:
-
如果独立线程正在从列表的深层副本中删除,您如何确保他们的工作有意义地同步?
-
Eric,深拷贝只是为了及时作为缓存的快照,改变它不应该反映在实际的缓存中。
-
旁注:“为了缩短时间……我对它进行了深度克隆”:这就是“过早优化万恶之源”这一短语存在的确切原因。任何重要对象的深度克隆都不太可能是快速操作。您始终应该衡量以了解您的“优化”实际上是什么。
标签: c# list c#-4.0 concurrency locking