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}
本文分享自微信公眾號 - 字母哥課堂(zimug_blog)。
如有侵權,請聯絡 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。
- 長篇圖解java反射機制及其應用場景
- 併發程式設計系列之Lock鎖可重入性與公平性
- java併發程式設計JUC第十二篇:AtomicInteger原子整型
- java併發程式設計JUC第十一篇:如何線上程之間進行對等資料交換
- java併發程式設計JUC第十篇:CyclicBarrier執行緒同步
- java併發程式設計JUC第九篇:CountDownLatch執行緒同步
- java併發程式設計JUC第八篇:ConcurrentHashMap
- java併發程式設計工具類JUC第七篇:BlockingDeque雙端阻塞佇列
- java併發程式設計工具類JUC第六篇:SynchronousQueue同步佇列
- java併發程式設計工具類JUC第五篇:PriorityBlockingQueue優先順序佇列
- java併發程式設計工具類JUC第四篇:LinkedBlockingQueue連結串列佇列
- java併發程式設計工具類JUC第三篇:DelayQueue延時佇列
- java併發程式設計工具類JUC第二篇:ArrayBlockingQueue
- java併發程式設計工具類JUC第一篇:BlockingQueue阻塞佇列
- 快速入門Redis呼叫Lua指令碼及使用場景介紹
- Mybatis plus通用欄位自動填充的最佳實踐總結
- 詳解執行緒池的作用及Java中如何使用執行緒池
- Java9系列第九篇-對HTTP2協議的支援與非阻塞HTTP-API
- 跨站資源共享CORS原理深度解析
- 你以前看的執行緒狀態轉換圖可能都是錯的-圖解併發程式設計第二篇