我注意到你可以調用Queue.Synchronize來獲得一個線程安全的隊列對象,但是同樣的方法在隊列<T>上不可用。有誰知道爲什麼?似乎有點奇怪。.NET爲什麼沒有通用的同步隊列?
回答
更新 - 在.NET 4中,現在有在System.Collections.Concurrent ConcurrentQueue<T>
,這裏http://msdn.microsoft.com/en-us/library/dd267265.aspx記錄。有趣的是,它的IsSynchronized方法(正確)返回false。
ConcurrentQueue<T>
是一個完全徹底的重寫,創建隊列的副本來枚舉,並使用先進的非鎖定技術,如Interlocked.CompareExchange()
和Thread.SpinWait()
。
這個答案的其餘部分仍然相關,因爲它涉及到舊的Synchronize()和SyncRoot成員的消亡,以及爲什麼它們從API的角度來說工作得不好。
按Zooba的評論中,BCL團隊認爲太多的開發者誤解同步的目的(以及在較小程度上,SyncRoot上)
布賴恩Grunkemeyer描述這對BCL團隊博客一對夫婦回到頂端: http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx
關鍵問題是獲取正確的鎖定粒度,其中一些開發人員會天真地使用多個屬性或方法在「同步」集合上並相信他們的代碼是線程安全的。布賴恩用隊列作爲他的榜樣,
if (queue.Count > 0) {
object obj = null;
try {
obj = queue.Dequeue();
開發者沒有意識到,計數可能被另一個線程改變出列被調用之前。
強迫開發人員在整個操作中使用顯式鎖定語句意味着防止這種虛假的安全感。
正如Brian所說,刪除SyncRoot的部分原因是它主要是爲了支持Synchronized而引入的,但也因爲在很多情況下鎖定對象有更好的選擇 - 大多數情況下,Queue實例本身,或
private static object lockObjForQueueOperations = new object();
的類擁有的隊列實例...
這後一種方法是最安全的,通常,因爲它避免了其他一些常見的陷阱:
正如他們所說,threading is hard,並使它看起來容易可能是危險的。
(我假設你的意思是隊列<牛逼>的第二個。)
我不能明確回答這個問題,除了IsSynchronized和SyncRoot上屬性(但不同步()明確)從繼承ICollection接口。沒有任何通用集合使用此接口,並且接口不包含SyncRoot。
至於爲什麼它沒有被包括在內,我只能推測它們沒有被用在圖書館設計者所期望的方式中,或者他們只是沒有被足夠用來證明將它們保留在較新的集合中。
您可能會發現並行CTP值得檢查;這裏是從誰是把它在一起的傢伙博客條目漂亮的外用:
Enumerating Concurrent Collections
這是不太一樣的東西,但它可能會解決你的問題更大。 (他們甚至使用Queue<T>
與ConcurrentQueue<T>
爲榜樣。)
有一個現在,在.NET 4.0中:
ConcurrentQueue<T>
在System.Collections.Concurrent
- 1. 爲什麼Cocoa中沒有隊列?
- 2. 爲什麼ArrayList沒有實現隊列?
- 3. 爲什麼Outlook沒有同步
- 4. 使用同步塊的同步隊列
- 5. 爲什麼我的回調沒有使用異步隊列進行觸發?
- 6. 爲什麼我的隊列沒有出隊?
- 7. 同步隊列
- 8. 不是ruby隊列線程安全爲什麼隊列不同步?
- 9. FIFO隊列同步
- 10. 爲什麼fork同步很有用?
- 11. 爲什麼.NET中隊列的底層實現使用數組?
- 12. 爲什麼從隊列(雙端隊列)
- 13. 爲什麼在.net中沒有異步文件刪除?
- 14. 爲什麼隊列結果只有通過更改機制纔有所不同?
- 15. 爲什麼甚至wait()被調用時,線程沒有通過內部同步
- 16. 爲什麼dispatchQueue.main給我同步或異步的選項,如果主隊列始終是同步
- 17. 爲什麼隊伍不同?
- 18. 我的步驟有什麼問題,爲什麼沒有輸出?
- 19. 隊列有什麼問題?
- 20. 爲什麼要同步一個同步列表?
- 21. 爲什麼進程沒有收到隊列事件?
- 22. 爲什麼在jdk中沒有隊列或堆棧API
- 23. 爲什麼消息隊列中沒有輪詢/選擇機制?
- 24. 爲什麼最大優先級隊列沒有DECREASE KEY?
- 25. 爲什麼打印張量流隊列沒有輸出?
- 26. AJAX:同步或隊列?
- 27. 同步循環隊列
- 28. C#線程隊列同步
- 29. 有沒有辦法看到SonicMQ隊列用戶是什麼?
- 30. 爲什麼.net項目沒有designer.cs?
我不同意你的意見一致。有趣的是,MSDN的鎖定文檔中提到「通常情況下,表達式就是這個」http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.71%29.aspx – dvogel 2010-08-16 03:07:20