2012-06-24 93 views
3

我有一個線程服務器應用程序,存儲List<Item> dataList。有一個寫入線程可以修改,添加和刪除列表中的項目,以及從該列表讀取的多個線程。這段代碼需要什麼樣的同步?

需要什麼樣的同步來確保寫操作按照被調用的順序發生,併爲讀操作提供最大性能,即如果寫操作繁忙,讀操作必須在讀操作前提供先前的值。

我目前使用ReaderWriterLockSlim是因爲它具有獨立的讀寫鎖定功能,但感覺好像有很多昂貴的開銷調用ReadLocks是不必要的,因爲我想要的只是爲了保證寫入順序?

據我瞭解,閱讀引用類型和值類型應提供原子訪問,所以鎖定可能沒有必要?

性能是一個大問題,它似乎像我同步結構可以通過頗有幾分改進的優化。

回答

2

聽起來像是你有一個生產者/消費者模式。在.Net 4中,System.Threading.Concurrent命名空間中有ConcurrentQueue<T> class。只有在添加和從隊列中刪除時纔會進行同步。

0

如果沒有同步,讀操作可能會在寫操作前後得到部分信息(例如:舊列表爲30%,新列表爲70%)。 如果這不是問題,那麼只要有一個作者,就不需要使用任何同步。

如果您的列表包含對象,您可能更願意將新數據寫入新對象,然後將此新元素與內置對象交換。 更改引用應該是原子的,除非有一些我不知道的內部機制。

Object temp = new Object(); 
temp.value = 5; 
temp.name = "whatever"; 
list[5] = temp; 

代替:

list[5].value = 5; 
list[5].name = "whatever"; 
+0

訪問經由直接的方法的項屬性不大於使用間接指針不同。同樣的事情,生產者線程仍然可以改變項目的屬性。 –

-1

ReaderWriterLockSlim在這裏並不是真的需要,除非有機會因爲某些重要原因而無法進入鎖定。
一個簡單Lock(syncObj)就足夠了,只是鎖定到位之前讀/寫操作。

如果需要TryEnter,我們需要查看您的代碼。

+0

就理解鎖而言,這並不理想,因爲基本上只有一個線程可以一次讀取,因爲我們鎖定了同一對象上的讀取和寫入。 – Vort3x

+0

是的,你是正確的,ReaderWriterLockSlim會給你一個很好的解決方案。併發隊列不夠好,導致1.您沒有使用隊列,2.如果更改項目,您的客戶可能會訪問無效數據。 –