我可以不鎖定,從多個線程安全地調用List.AddRange(r)?如果不是,我會遇到什麼樣的麻煩?是列表<T> .AddRange()線程安全嗎?
回答
沒有,its documentation不說它是線程安全的,因此它不是。
公共靜態(在Visual Basic中共享) 此類型的成員是線程安全的。 任何實例成員不是 保證是線程安全的。
至於什麼可以去錯了,想什麼的AddRange(newItems)作用:
- 檢查是否存在內部數組中足夠的空間
- 如果不是:
- 分配新陣列
- 將當前項目複製到新陣列
- 將字段設置爲指向新的陣列唉
- 複製newItems正確的本地內部數組
- 更新在「計數」字段(這是用來控制下一個項目插入)
現在想想會出現什麼如果上述情況與對AddRange()的另一個調用混合在一起,或者甚至只是一個讀取某個項目的調用,都會發生。
不,它不是線程安全的。
線程A可以打電話給你的AddRange名單上。它可以在收集和切換線程上部分迭代。
線程B可以調用添加/刪除等前線程A已經完成。
不,但我想補充說,在一個鎖內執行myList.AddRange(...);
要比做幾個lock (syncLock) { myList.Add(...) };
更有效率。
哪種類型的麻煩,你會碰上?當一個線程正在添加一個項目,而另一個線程正在枚舉列表時,List<T>
會拋出一個異常,因爲它會執行一些內部版本控制,因爲它想阻止我們可憐的開發人員碰到令人討厭的副作用。
另外,List<T>
在內部保存在其中存儲其項的數組。也許在一個數組中設置一個項目是非常原子的,但是每當這個數組的容量達到時,就會創建一個新的項目,並且項目將從舊項目中複製過來。因此,當一個線程想要在發生複製時添加某些內容時,可以想象事情會不同步。
優秀的答案,謝謝。 =) – 2010-10-28 14:40:27
在.NET Framework 4.0之前,沒有.NET集合是線程安全的。然後您將被要求鎖定它,然後在代碼
Collections and Synchronization (Thread Safety)
中訪問它。
在另一方面,.NET Framework 4中。0引入包含細粒度Thread-Safe Collections
的新名稱空間System.Collections.Concurrent
。
最後,如果你可以使用.NET Framework 4.0中,我強烈建議你這樣做對你所需要的,否則,請務必要修改或訪問每次鎖定集合。
此外,靜態集合應該是線程安全的,但要注意,作爲成員,但不保證。
編輯#1
後由於史蒂夫湯森的評論進一步驗證,我承認有.NET框架中的三個線程安全的集合開始3.0版本:
- SynchronizedCollection Generic Class;
- SynchronizedKeyedCollection Generic Class;
- SynchronizedReadOnlyCollection Generic Class。
我很抱歉,我剛剛得知自己exitense自己。 =)
不正確的,也有一些在'System.Collections.Generic'在這裏工作,早於4.0 – 2010-10-28 18:14:48
@Steve湯森:驗證後,你是對的,我錯了。此外,'IList
沒問題。我欠你一個提及4.0集合的+1。 – 2010-10-28 18:48:42
根據您的使用,SynchronizedCollection可以工作。
你必須沒有單次AddRange
雖然。如果您僅使用此操作爲種子收集種子,則可以這樣做,因爲存在IEnumerable
構造函數重載。
+1我剛剛學到了一些新東西!謝謝! =) – 2010-10-28 18:44:04
感謝您的upvote。我想告訴你,我編輯了我的答案,以反映你向我提供的這些新信息(我們所有人)。 – 2010-10-28 18:55:02
- 1. 是否列表<BlockingCollection <T>>線程安全嗎?
- 2. 列表線程安全嗎?
- 3. 是列表<T>構造函數線程安全嗎?
- 4. 多線程列表AddRange
- 5. 列表<T>線程安全
- 6. 是List <T>(列表<T>)構造函數線程安全嗎?
- 7. 列表複製線程安全嗎?
- 8. 此列表<T>屬性線程安全嗎?
- 9. 是java.sql.Connection線程安全嗎?
- 10. 是CreateChildContainer()線程安全嗎?
- 11. 是Thread.getStackTrace()線程安全嗎?
- 12. 是DocumentBuilder.parse()線程安全嗎?
- 13. 是javax.sql.DataSource線程安全嗎?
- 14. 是TcpClient.Available線程安全嗎?
- 15. 是sqlite.swift線程安全嗎?
- 16. 是winsock2線程安全嗎?
- 17. 是unique_ptr線程安全嗎?
- 18. 是SplittableRandom.split()線程安全嗎?
- 19. 線程安全(是嗎?)
- 20. 是IP2Location線程安全嗎?
- 21. 是System.DirectoryServices.AccountManagement.GroupPrincipal線程安全嗎?
- 22. 是Microsoft.Practices.EnterpriseLibrary.Data.Database.SetParameterValue線程安全嗎?
- 23. 是java.util.UUID線程安全嗎?
- 24. 是enumerateUsingBlock:線程安全嗎?
- 25. 是java.util.concurrent.Future線程安全嗎?
- 26. 是DatagramSocket.send線程安全嗎?
- 27. 是長線程安全嗎?
- 28. 是SpelExpression線程安全嗎?
- 29. 是UImage.AsPNG()線程安全嗎?
- 30. 是ArrayDescriptor線程安全嗎?
btw - 「有什麼樣的麻煩?」 - 你可能會得到一個異常,在一些隨機的時間多線程衝突 – 2010-10-28 20:34:31