我的理解是,他們沒有。請確認。鎖確保列表元素的線程安全嗎?
假設我有一個包含列表的處理器對象<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