2011-07-18 22 views

回答

28

是的,它是線程安全的,是的它避免你使用鎖在各地(無論這意味着什麼)。當然,這隻會爲您提供線程安全訪問存儲在此字典中的數據,但如果數據本身不是線程安全的,那麼您當然需要同步對它的訪問。想象一下,例如,你已經存儲在這個緩存中List<T>。現在thread1讀取這個列表(以線程安全的方式,因爲併發字典保證你這個),然後開始枚舉這個列表。在同一時間,thread2從緩存中獲取這個非常相同的列表(以線程安全的方式,因爲併發字典可以保證這一點)並寫入列表(例如,它會添加一個值)。結論:如果你沒有同步thread1,它會遇到麻煩。

就使用它作爲緩存而言,好吧,這可能不是一個好主意。爲了緩存,我會推薦你​​已經內置到框架中的東西。例如,類別爲MemoryCache。其原因在於System.Runtime.Caching程序集內置的內容很明顯是爲緩存而構建的=>如果您開始在內存不足時啓動內存不足,則會自動過期數據,並且您甚至可以能夠使用諸如memcached,AppFabric,......之類的東西將緩存分佈到多個服務器上,所有這些你都無法用併發字典來實現。

+2

MemoryCache類像ConcurrentDictionary一樣是線程安全的嗎? – michael

+1

@michael,是的,它是線程安全的,但絕對相同的說法對於同步訪問您可能正在存儲到此緩存中的非線程安全對象是非常正確的。 –

+0

哦,我明白那一部分。但是,爲了讓其他讀者能夠理解我將重申它。你說'ConcurrentDictionary'和'MemoryCache'類都是線程安全的,但其中的內容不能保證是線程安全的。 :) – michael

3

您仍可能需要以與您可能需要數據庫中的事務相同的方式使用鎖定。 「併發」部分意味着字典將繼續在多個線程間正常工作。

內置到併發集合中的是TryGetValue和TryRemove,它確認有人可能首先刪除一個項目。內置鎖定在粒度級別上,但您仍需要考慮在這些情況下應採取的措施。對於緩存而言,這通常無關緊要 - 即它是一個冪等操作。

re:緩存。我感覺,它取決於你在緩存中存儲什麼+你在做什麼。與使用對象相關的鑄造成本。可能對於大多數基於Web的東西,MemCache更適合上面的建議。