HashMap 對比ConcurrentHashMap 對比SynchronizedMap – 如何在 Java 中同步 HashMap

已發表: 2015-01-29

Crunchify ConcurrentHashMap 與。同步地圖示例 HashMap是 Java 中非常強大的數據結構。 我們每天都在使用它,幾乎在所有應用程序中都使用它。 我之前寫過很多例子,關於如何實現線程安全緩存,如何將 Hashmap 轉換為 Arraylist?

我們在上面的兩個示例中都使用了 Hashmap,但這些都是非常簡單的 Hashmap 用例。 HashMap is a non-synchronized集合類。

您有以下任何問題嗎?

  • ConcurrentHashMap 和 Collections.synchronizedMap(Map) 有什麼區別?
  • ConcurrentHashMap 和 Collections.synchronizedMap(Map) 在性能方面有什麼區別?
  • ConcurrentHashMap 與 Collections.synchronizedMap()
  • 熱門 HashMap 和 ConcurrentHashMap 面試題

在本教程中,我們將介紹所有上述查詢以及why and how同步 Hashmap?

為什麼?

Map 對像是存儲元素的關聯容器,由唯一標識的key和映射的value組合而成。 如果您有非常高並發的應用程序,您可能希望在不同的線程中修改或讀取鍵值,那麼使用 Concurrent Hashmap 是理想的。 最好的例子是處理並發讀/寫的生產者消費者。

那麼線程安全的 Map 是什麼意思呢? 如果multiple threads同時訪問一個哈希映射,並且至少有一個線程在結構上修改了映射,則must be synchronized externally以避免內容視圖不一致。

如何?

有兩種方法可以同步 HashMap

  1. Java 集合 synchronizedMap() 方法
  2. 使用 ConcurrentHashMap

並發哈希映射

  • 當您的項目需要非常高的並發性時,您應該使用 ConcurrentHashMap。
  • 它是線程安全的,無需同步whole map
  • 使用鎖完成寫入時,讀取可能會非常快。
  • 在對象級別沒有鎖定。
  • 鎖定在哈希圖存儲桶級別的粒度要細得多。
  • 如果一個線程嘗試修改它而另一個線程正在對其進行迭代,則 ConcurrentHashMap 不會引發ConcurrentModificationException
  • ConcurrentHashMap 使用大量鎖。

同步HashMap

  • 對象級別的同步。
  • 每個讀/寫操作都需要獲取鎖。
  • 鎖定整個集合是一種性能開銷。
  • 這實質上只允許訪問整個映射的一個線程並阻止所有其他線程。
  • 它可能會引起爭用。
  • SynchronizedHashMap 返回Iterator ,它在並發修改時快速失敗。

現在讓我們看一下代碼

  1. 創建類CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. 為每個 HashTable、SynchronizedMap 和 CrunchifyConcurrentHashMap 創建對象
  3. 從 Map 添加和檢索 500k 條目
  4. 測量開始和結束時間並以毫秒為單位顯示時間
  5. 我們將使用 ExecutorService 並行運行5 threads

這是一個Java代碼:

  • shutdown()表示執行器服務不再接受傳入任務。
  • awaitTermination()在關閉請求後調用。

因此,您需要先關閉 serviceExecutor,然後阻塞並等待線程完成。

Eclipse 控制台結果: