好吧,我無法正確理解多線程場景。對不起再次提出類似的問題,我只是在互聯網上看到許多不同的「事實」。在多線程場景中正確鎖定列表<T>?
public static class MyClass {
private static List<string> _myList = new List<string>;
private static bool _record;
public static void StartRecording()
{
_myList.Clear();
_record = true;
}
public static IEnumerable<string> StopRecording()
{
_record = false;
// Return a Read-Only copy of the list data
var result = new List<string>(_myList).AsReadOnly();
_myList.Clear();
return result;
}
public static void DoSomething()
{
if(_record) _myList.Add("Test");
// More, but unrelated actions
}
}
的想法是,如果錄像被激活,調用DoSomething的()獲取記錄在內部列表和StopRecording()被調用時返回。
我的規格是這樣的:
- 的StartRecording不被認爲是線程安全的。用戶應該在沒有其他線程調用DoSomething()的情況下調用此方法。但是,如果它有可能,那會很好。
- StopRecording也不是正式的線程安全的。再說一次,如果可能的話,它會很好,但那不是必需的。
- DoSomething的必須是線程安全的
的常用方法似乎是:
public static void DoSomething()
{
object _lock = new object();
lock(_lock){
if(_record) _myList.Add("Test");
}
// More, but unrelated actions
}
另外,聲明一個靜態變量:
private static object _lock;
public static void DoSomething()
{
lock(_lock){
if(_record) _myList.Add("Test");
}
// More, but unrelated actions
}
然而,this answer說,這不會阻止其他代碼訪問它。
所以我想
- 我將如何正確地鎖定一個列表?
- 我應該在我的函數中創建鎖對象還是作爲靜態類變量?
- 我可以將Start和StopRecording的功能封裝在鎖定塊中嗎?
- StopRecording()會做兩件事:將布爾變量設置爲false(以防止DoSomething()添加更多東西),然後複製列表以將數據的副本返回給調用者。我假設_record = false;是原子的,將立即生效?所以通常我根本不用擔心多線程,除非其他線程再次調用StartRecording()。
在一天結束時,我正在尋找一種方式來表達「好的,這個列表是我的,現在所有其他線程都必須等到我完成它」。
如果我明白你需要看看,我有同樣的問題 https://stackoverflow.com/a/44414120/4745606 – 2017-06-07 13:33:32