2013-08-01 99 views
2

首先,我將描述我想要的內容,然後詳細說明我正在考慮的可能性。我不知道哪個是最好的,所以我想要一些幫助。Hash Map的線程安全實現

我有一個散列圖,我在Servlet上讀取和寫入操作。現在,由於這個Servlet在Tomcat上,我需要哈希映射是線程安全的。基本上,當它被寫入時,沒有其他東西應該寫入它,也沒有東西能夠讀取它。

我看過ConcurrentHashMap,但注意到它的get方法不是線程安全的。然後,我看到了鎖和一些叫做synchronized的東西。

我想知道哪個是最可靠的方法。

+9

ConcurrentHashMap.get不是線程安全的方式?你在尋找什麼級別的粒度?通過「當它被寫入」時,你的意思是說將會有多個* put操作,還是每個人都是原子的就足夠了? –

+0

看到API文檔,我認爲它不是線程安全的。如果說3個人決定進行相同的放置操作,那麼對於哈希映射可以有多個放置操作。 – pratnala

+2

@pratnala事實上,它允許併發操作不會使它不是線程安全的。 – assylias

回答

3

編輯:刪除虛假信息

在任何情況下,​​關鍵字是一個安全的賭注。它在​​塊內阻止任何線程訪問對象。

// Anything can modify map at this point, making it not thread safe 
map.get(0); 

,而不是

// Nothing can modify map until the synchronized block is complete 
synchronized(map) { 
    map.get(0); 
} 
+0

容器中每個「Servlet」只有一個實例。所有映射的請求都將通過同一個實例。如果您有實例字段,則每個請求都可以訪問它們。 –

+0

儘管有一個servlet實例,但是請求在不同的線程中執行,即servlet的'service()'方法可以併發執行(除非Servlet被聲明爲'SingleThreadModel')。因此,可以從多個請求處理線程中調用在Servlet類中聲明的實例變量。 –

+0

Ack。你(都)是對的,我不知道我在想什麼。我認爲我們(在工作中)通過一系列測試證明了這一點。我會刪除我的答案的那部分。 – Deactivator2

3

Collections.synchronizedMap(new HashMap<K, V>);

返回由指定映射支持的同步(線程安全的)映射。爲了保證串行訪問,通過返回的映射完成對底圖的所有訪問是非常重要的。

當務之急是用戶迭代它的任何集合視圖時返回的地圖上手動同步:

+0

你是什麼意思?「通過返回的排序映射完成對支持排序映射的所有訪問是非常重要的」? – pratnala

+0

錯誤地複製了Collection.synchronizedSortedMap()的描述,我的意思是說你傳入的地圖仍然不會是線程安全的 –

+0

我仍然不理解描述。 – pratnala

16

ConcurrentHashMap.get()是線程安全的。

你可以用Collections.synchronizedMap()包裝HashMap線程安全。

+0

有什麼區別? – naXa

+0

@naXa ConcurrentHashMap允許併發訪問,並且'synchronized'不允許併發訪問。 –

2

我想建議你去與ConcurrentHashMap,你所提到的要求,前面我也有過同樣類型的需求爲我們的應用程序,但我們更少關注性能方面。

我跑都ConcurrentHashMap和地圖由Colecctions.synchronizedMap();返回,在不同類型的負載,並使用JMeter的同時發射多線程和我使用JProfiler的。畢竟這些測試,我們來到了結論,即通過地圖返回Colecctions.synchronizedMap()監測他們並不像ConcurrentHashMap那樣有效。

我寫了一個post也對我的經驗都一樣。

謝謝

0

這是ConcurrentHashMap類的要點。它可以保護你的收藏品,當你有超過1個線程。