java並發編程工具類JUC第八篇:ConcurrentHashMap


在之前的文章中已經為大家介紹了java並發編程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、BlockingDeque接口,本文為系列文章第八篇。

由於Java程序員常用的HashMap的操作方法不是同步的,所以在多線程環境下會導致存取操作數據不一致的問題,Map接口的另一個實現類Hashtable 雖然是線程安全的,但是在多線程下執行效率很低。為了解決這個問題,在java 1.5版本中引入了線程安全的集合類ConcurrentMap

java.util.concurrent.ConcurrentMap接口是Java集合類框架提供的線程安全的map,這意味着多線程同時訪問它,不會影響map中每一條數據的一致性。ConcurrentMap接口有兩個實現類ConcurrentHashMap和ConcurrentSkipListMap,經常被使用的是ConcurrentHashMap,我們來重點關注它。

1.創建ConcurrentHashMap對象

通過下面的代碼創建ConcurrentHashMap

// 創建容量為8,負載系數為0.6的ConcurrentHashMap
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);

使用上面的代碼,我們創建一個叫做numbers的ConcurrentHashMap對象。

  • Key - 用於關聯Map中每個元素的唯一標識
  • Value - Map中每個元素,可以通過key值獲取value

需要我們特別注意的是new ConcurrentHashMap<>(8, 0.6).

  • capacity容量 - 第一個參數表示這個map的容量是8,也就是說這個對象可以存儲8個鍵值對.
  • loadFactor負載因子 - 這個map對象的負載因子是 0.6. 這意味着,每當我們的哈希表被填滿60%的時候,條目就會被移動到一個新的哈希表,其容量大小是原來哈希表的兩倍。

默認容量與負載因子
我們還可以通過下面的代碼初始化一個ConcurrentHashMap對象,默認情況下capacity=16,loadFactor=0.75

ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();

2.ConcurrentHashMap常用方法

2.1. 向ConcurrentHashMap插入元素

  • put(K,V) - 向map中插入key/value 鍵值對數據
  • putAll(map) - 把另一個map中的所有entries插入到當前的map中
  • putIfAbsent(K,V) - 向map中插入key/value 鍵值對數據,如果該鍵值對的key在map不存在則插入數據,否則不做操作。
import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {
        // 創建ConcurrentHashMap 用於保存偶數
        ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();

        // 使用put()方法插入數據
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);

        // 使用putIfAbsent()插入數據
        evenNumbers.putIfAbsent("Six", 6);
        System.out.println("偶數集合ConcurrentHashMap: " + evenNumbers);

        //創建ConcurrentHashMap用於保存整數
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);

        // 使用putAll()插入數據
        numbers.putAll(evenNumbers);
        System.out.println("整數集合ConcurrentHashMap: " + numbers);
    }
}

輸出結果:

偶數集合ConcurrentHashMap: {Six=6, Four=4, Two=2}
整數集合ConcurrentHashMap: {Six=6, One=1, Four=-4, Two=2}

2.2.批量獲取ConcurrentHashMap 元素

  • entrySet()- 獲取 map中key/value 鍵值對集合
  • keySet()- 獲取map中所有的key的集合
  • values()- 獲取map中所有的value的集合
import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();

        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 獲取 map中key/value 鍵值對集合
        System.out.println("Key/Value mappings: " + numbers.entrySet());

        // 獲取map中所有的key的集合
        System.out.println("Keys: " + numbers.keySet());

        // 獲取map中所有的value的集合
        System.out.println("Values: " + numbers.values());
    }
}

輸出結果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Key/Value mappings: [One=1, Two=2, Three=3]
Keys: [One, Two, Three]
Values: [1, 2, 3]

2.3. 獲取指定Key元素的value值

  • get() - 獲取指定key元素的value值,如果key不存在返回null
  • getOrDefault() - 獲取指定key元素的value值,如果key不存在返回一個指定的默認值
import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 獲取指定key元素的value值,如果key不存在返回null
        int value1 = numbers.get("Three");
        System.out.println("Using get(): " + value1);

        // 獲取指定key元素的value值,如果key不存在返回一個指定的默認值
        int value2 = numbers.getOrDefault("Five", 5);
        System.out.println("Using getOrDefault(): " + value2);
    }
}

輸出結果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Using get(): 3
Using getOrDefault(): 5

2.4.移除ConcurrentHashMap中的元素

  • remove(key) - 根據指定的key刪除map中的元素,並將該元素返回
  • remove(key, value) - 只有當map中存在指定的鍵映射到指定的值時,才會從map中刪除條目,並返回一個布爾值。返回true表示刪除成功,否則表示map中沒有這個鍵值對。
import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 根據指定的key刪除map中的元素,並將該元素返回
        int value = numbers.remove("Two");
        System.out.println("Removed value: " + value);

        // 只有當map中存在指定的鍵映射到指定的值時,才會從map中刪除條目,並返回一個布爾值。
        boolean result = numbers.remove("Three", 3);
        System.out.println("Is the entry {Three=3} removed? " + result);

        System.out.println("Updated ConcurrentHashMap: " + numbers);
    }
}

輸出結果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Removed value: 2
Is the entry {Three=3} removed? True
Updated ConcurrentHashMap: {One=1}

歡迎關注我的博客,里面有很多精品合集

  • 本文轉載注明出處(必須帶連接,不能只轉文字):字母哥博客

覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力! 。另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM