2

在我的應用程序中,我將使用Map。如果多個線程寫入單個映射,則使用哪個映射實現

  • 多個線程將寫入數據到這張地圖。寫操作太多了。
  • 但是,在每次寫入期間,提供給映射的數據都有不同的鍵。
  • 地圖中的數據不會在應用程序的任何位置讀取。
  • 有一段時間,內容將被轉儲到一個文件。

我想了解以下內容:

  1. 在這種情況下,有必要同步寫入方法?
  2. ConcurrentHashMap是否適合我的需求?
  3. 如果不是,那麼 這個案例中正確的Map實現將使用什麼?
+2

_「在地圖中的數據不會在應用程序的任何點讀」 _再_「在一段時間後的內容會被傾倒到一個文件」 _ - 你怎麼這麼轉儲到一個文件,而不閱讀地圖? –

+1

這兩點是不兼容的:「地圖中的數據不會在應用程序的任何位置讀取」和「偶爾會將內容轉儲到文件中」。沒有讀出地圖的全部內容,內容不能轉儲到文件中。 –

+1

您可能還想考慮爲每個線程保留一個映射,然後在轉儲到文件時合併它們。然後,只有在轉儲到文件時,纔會阻止對地圖的訪問,而不是爲每次寫入都阻止。 – xp500

回答

7

關注以下幾點:

  • 被饋送到地圖中的數據具有不同的密鑰在每次寫入

  • 在地圖中的數據將不會在任何時候讀在應用

你並不需要一個Map在所有。我假設,當你聲明地圖中的數據不會被讀取時,你的意思是你沒有做map.get(someKey),而是你將遍歷整個地圖以將數據存儲在文件中(或者任何數據源使用)。

這一點:

  • 在一段時間後的內容將被轉儲到一個文件

加強上述建議。

着眼於這一點:

  • 多個線程將數據寫入到這個map.The寫操作太多。

最好的建議是使用BlockingQueue。作爲實施,您可以使用LinkedBlockingQueue

如果您使用Java同步從Map轉儲數據並且想要/需要以Map的形式恢復此數據,請使用ConcurrentHashMap。如果這不是您的用例的一部分,因爲您將以其他方式從文件中讀取數據,請避免使用Map並使用BlockingQueue

+0

您錯過了將整個地圖轉儲到文件中的部分。既然鍵也是地圖的內容,我會爭辯說這個答案沒有正確地解決這個問題。 – John

+0

@ user3360241由於鍵沒有用處,因爲它們總是唯一的,那麼這個部分就沒有意義了。除非關鍵字是在'Map'(除了OP之外沒有人知道)的值內找不到的相關數據,否則它看起來不太好。或者,另一方面,如果它有價值,則將該* key *存儲在值的字段中並保存。再次,'Map'選項在這個用例中沒有用處。 –

+0

如果操作者想在另一個應用程序中重建Map文件,該怎麼辦?但正如你所說的,鑰匙可以嵌入到大多數情況下的價值中,但不是爲了這個。 – John

-1

如果您真的需要Map,您需要的是ConcurrentHashMap。詳細瞭解它here

-1

正如你也說:ConcurrentHashMap的似乎符合您的要求。它是線程安全的,無需同步整個地圖。讀取可以非常快速地進行,而寫入是通過鎖定完成的。

-3

所有你的鑰匙都是獨一無二的,所以你不一定需要確保地圖的完整性,同步但你需要它的時候,你實際上將被寫入文件。使用ConccurentHashMap或正常的同步映射都適合你。您可以在沒有Map的情況下將鍵/值存儲在某個對象中,並將該對象存儲在同步列表中。

+1

擁有不同的密鑰決不意味着寫入映射不需要同步。 –

+0

來自例如['TreeMap'的Javadoc](https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html):*如果多個線程同時訪問地圖,並且至少有一個線程在結構上修改了地圖,它必須在外部同步*。 – Turing85

+0

@JohnBollinger和圖靈:是的,我明白這一點。我的問題是,如果所有將要插入的鍵都是唯一的,並且地圖僅用於書寫目的,那麼可能的危害是什麼?例如:從一個線程寫入可能不會提供給另一個線程..足夠公平..當你寫入文件時唯一的危害是你可能看不到所有的更新..正確嗎?我錯過了什麼 ?我同意上面不是一個完美的評論 – Geek

0
  1. 沒有

但是我覺得這是一個矛盾:

  • 在地圖中的數據不會被應用程序在任何時候讀
  • 一旦在一段時間內容將被轉儲到一個文件。

你怎麼可以轉儲到一個文件中不讀呢?

我認爲這是肯定地說,ConcurrentHashMap的反正可以處理這種情況,所以要爲它。

+0

一些解釋會很好,而不是簡單地說「是」或「否」。 – Turing85