2014-01-24 42 views
3

問題: 我有一個ViewModel基類,它有一個HashMap來存儲ViewModel的屬性值。不過,我遇到了一個間歇性錯誤,其中一個讀取來自此集合(在一個單獨的線程上)在添加項目後直接返回null。Hashtable,ConcurrentHashMap和Data Visibility

private HashMap<String, Serializable> _propertyValues = new HashMap<String, Serializable>(); 

爲例:我希望在用戶ID被提供給視圖模型來獲取用戶信息。

ViewModel連接到用戶ID的PropertyChanged。屬性更改處理程序創建一個後臺線程來提取值。後臺線程讀取用戶標識,然後從服務器獲取。

我們正在看到的是,在少數情況下,後臺線程直接在提供值(線程1)之後從屬性hashmap(線程2)讀取null。

我的想法:我懷疑這是由於data visibility和沒有線程安全收集。在審查線程安全選項時,我碰到:

  1. Hashtable - 似乎社區認爲這已過時,並阻止其使用。
  2. ConcurrentHashMap的 - 好像我還是會碰到我的問題,由於缺乏這種可靠的同步
  3. Collections.synchronizedMap(圖) - 在你如何使用它似乎特別,不知道是否有過的Hashtable
好處

此時我覺得Hashtable是我想要的,但可以使用確認。 :)

使用案例:

  1. 100ish讀取所有一次,每分鐘左右。
  2. 頻繁從UI線程寫入
  3. 定期從後臺線程中讀取需要精確值的線程。後臺線程讀取,正好在UI線程寫入之後。

感謝, 三分球

+0

您也可以使用鎖定,以便其他進程無法訪問信息,直到寫入鎖定被放棄。 – thatidiotguy

+1

鎖可能是您唯一的選擇。看起來發生在你的情況是你*假設*的值已被寫入,但讀線程實際上在寫線程之前被調用,因此值爲空。您需要一個鎖來確保寫入線程在讀取線程訪問值之前完成。 – Jeshurun

+0

你的意思是「特別是你如何使用它」? 'synchronizedMap(new HashMap())'的優點是''HashMap'已經在過去的十年中發展,而'Hashtable'沒有。 –

回答

4

ConcurrentHashMap就做得很好。它有內部同步來防止這些問題。它也有其他方法,您可能會發現有用的,如putIfAbsent

它相對於Collections.synchronizedMap的主要缺點是內存佔用面積較大。

+1

+1 CHM的一個重要且獨特的優點是其迭代器的一致性。 –