我的理解是,他们没有。请确认。锁确保列表元素的线程安全吗?
假设我有一个包含列表的处理器对象<T>其中T是引用类型。
UI线程实例化处理器对象,并定期调用它来获取列表<T>。
处理器对象在构建时还会启动一个参考列表<T>的任务。
锁定用以保留访问列表<牛逼>在吸气和任务,以确保他们的名单<牛逼>独占访问。
public class Processor
{
private List<T> _list = new List<T>();
private Object _listLock = new Object();
public Processor()
{
// populate _list
Task t = new Task(Process);
t.Start();
}
public List<T> GetList()
{
lock(_listLock)
{
return _list;
}
}
private void Process()
{
while(!doneProcessing)
{
lock(_listLock)
{
// access and modify _list items
}
Thread.Sleep(...);
}
}
}
但即使名单<牛逼>被锁定在吸气剂,它没有问题返回列表参考,由处理器启动任务仍在修改引用类型列表中的元素,当它抓住了锁。
列表的元素仍然受到来自处理器的任务发生变化,并访问它们在UI线程不会是线程安全的。
如果我是正确的,一个明显的解决方案是,吸气返回填充了列表元素的深层副本一个新的列表。
public List<T> GetList()
{
lock(_listLock)
{
return _list.Select(t => t.Clone()).ToList();
}
}
你还能做什么?
不是答案,只是调用'ToList()'创建列表的副本。 – stuartd
您只能公开您使用的'List'中的方法,而不是整个列表。这样,您可以使用锁定来访问和修改项目。 –
你是否清楚这样一个事实:在修改列表中的元素时,像这样的列表上锁定时不会提供踩踏安全性? – Enigmativity