Java并發(fā)編程之詳解ConcurrentHashMap類
前言
由于Java程序員常用的HashMap的操作方法不是同步的,所以在多線程環(huán)境下會(huì)導(dǎo)致存取操作數(shù)據(jù)不一致的問題,Map接口的另一個(gè)實(shí)現(xiàn)類Hashtable 雖然是線程安全的,但是在多線程下執(zhí)行效率很低。為了解決這個(gè)問題,在java 1.5版本中引入了線程安全的集合類ConcurrentMap。
java.util.concurrent.ConcurrentMap
接口是Java集合類框架提供的線程安全的map,這意味著多線程同時(shí)訪問它,不會(huì)影響map中每一條數(shù)據(jù)的一致性。ConcurrentMap接口有兩個(gè)實(shí)現(xiàn)類ConcurrentHashMap和ConcurrentSkipListMap,經(jīng)常被使用的是ConcurrentHashMap,我們來重點(diǎn)關(guān)注它。
一、創(chuàng)建ConcurrentHashMap對(duì)象
通過下面的代碼創(chuàng)建ConcurrentHashMap
// 創(chuàng)建容量為8,負(fù)載系數(shù)為0.6的ConcurrentHashMap ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
使用上面的代碼,我們創(chuàng)建一個(gè)叫做numbers的ConcurrentHashMap對(duì)象。
- Key - 用于關(guān)聯(lián)Map中每個(gè)元素的唯一標(biāo)識(shí)
- Value - Map中每個(gè)元素,可以通過key值獲取value
需要我們特別注意的是new ConcurrentHashMap<>(8, 0.6)
.
- capacity容量 - 第一個(gè)參數(shù)表示這個(gè)map的容量是8,也就是說這個(gè)對(duì)象可以存儲(chǔ)8個(gè)鍵值對(duì)
- loadFactor負(fù)載因子 - 這個(gè)map對(duì)象的負(fù)載因子是 0.6. 這意味著,每當(dāng)我們的哈希表被填滿60%的時(shí)候,條目就會(huì)被移動(dòng)到一個(gè)新的哈希表,其容量大小是原來哈希表的兩倍。
默認(rèn)容量與負(fù)載因子
我們還可以通過下面的代碼初始化一個(gè)ConcurrentHashMap對(duì)象,默認(rèn)情況下capacity=16,loadFactor=0.75
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
二、ConcurrentHashMap常用方法
2.1. 向ConcurrentHashMap插入元素
put(K,V)
- 向map中插入key/value 鍵值對(duì)數(shù)據(jù)putAll(map)
- 把另一個(gè)map中的所有entries插入到當(dāng)前的map中putIfAbsent(K,V)
- 向map中插入key/value 鍵值對(duì)數(shù)據(jù),如果該鍵值對(duì)的key在map不存在則插入數(shù)據(jù),否則不做操作。
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { // 創(chuàng)建ConcurrentHashMap 用于保存偶數(shù) ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>(); // 使用put()方法插入數(shù)據(jù) evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); // 使用putIfAbsent()插入數(shù)據(jù) evenNumbers.putIfAbsent("Six", 6); System.out.println("偶數(shù)集合ConcurrentHashMap: " + evenNumbers); //創(chuàng)建ConcurrentHashMap用于保存整數(shù) ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); // 使用putAll()插入數(shù)據(jù) numbers.putAll(evenNumbers); System.out.println("整數(shù)集合ConcurrentHashMap: " + numbers); } }
輸出結(jié)果:
偶數(shù)集合ConcurrentHashMap: {Six=6, Four=4, Two=2} 整數(shù)集合ConcurrentHashMap: {Six=6, One=1, Four=-4, Two=2}
2.2.批量獲取ConcurrentHashMap 元素
entrySet()
- 獲取 map中key/value 鍵值對(duì)集合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 鍵值對(duì)集合 System.out.println("Key/Value mappings: " + numbers.entrySet()); // 獲取map中所有的key的集合 System.out.println("Keys: " + numbers.keySet()); // 獲取map中所有的value的集合 System.out.println("Values: " + numbers.values()); } }
輸出結(jié)果
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不存在返回nullgetOrDefault()
- 獲取指定key元素的value值,如果key不存在返回一個(gè)指定的默認(rèn)值
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不存在返回一個(gè)指定的默認(rèn)值 int value2 = numbers.getOrDefault("Five", 5); System.out.println("Using getOrDefault(): " + value2); } }
輸出結(jié)果
ConcurrentHashMap: {One=1, Two=2, Three=3}
Using get(): 3
Using getOrDefault(): 5
2.4.移除ConcurrentHashMap中的元素
remove(key)
- 根據(jù)指定的key刪除map中的元素,并將該元素返回remove(key, value)
- 只有當(dāng)map中存在指定的鍵映射到指定的值時(shí),才會(huì)從map中刪除條目,并返回一個(gè)布爾值。返回true表示刪除成功,否則表示map中沒有這個(gè)鍵值對(duì)。
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); // 根據(jù)指定的key刪除map中的元素,并將該元素返回 int value = numbers.remove("Two"); System.out.println("Removed value: " + value); // 只有當(dāng)map中存在指定的鍵映射到指定的值時(shí),才會(huì)從map中刪除條目,并返回一個(gè)布爾值。 boolean result = numbers.remove("Three", 3); System.out.println("Is the entry {Three=3} removed? " + result); System.out.println("Updated ConcurrentHashMap: " + numbers); } }
輸出結(jié)果
ConcurrentHashMap: {One=1, Two=2, Three=3}
Removed value: 2
Is the entry {Three=3} removed? True
Updated ConcurrentHashMap: {One=1}
到此這篇關(guān)于Java并發(fā)編程之詳解ConcurrentHashMap類的文章就介紹到這了,更多相關(guān)Java ConcurrentHashMap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)301跳轉(zhuǎn)和重定向的方法
301跳轉(zhuǎn)和重定向是做項(xiàng)目的時(shí)候經(jīng)常需要用到的,本文給大家分享的是在java中301跳轉(zhuǎn)和重定向的方法,需要的小伙伴參考下吧。2015-03-03Mybatis返回Map對(duì)象的實(shí)現(xiàn)
本文介紹了Mybatis和MybatisPlus在查詢數(shù)據(jù)庫時(shí)返回Map對(duì)象的多種實(shí)現(xiàn)方式,這些方法有助于優(yōu)化DAO層代碼,使其更加清晰和高效,下面就來具體介紹一下,感興趣的可以了解一下2024-09-09JavaWeb中獲取表單數(shù)據(jù)及亂碼問題的解決方法
這篇文章主要介紹了JavaWeb中獲取表單數(shù)據(jù)及亂碼問題的解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11idea每次新打開的項(xiàng)目窗口maven都要重新設(shè)置問題
這篇文章主要介紹了idea每次新打開的項(xiàng)目窗口maven都要重新設(shè)置問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11MyBatis實(shí)現(xiàn)簡單的數(shù)據(jù)表分月存儲(chǔ)
本文主要介紹了MyBatis實(shí)現(xiàn)簡單的數(shù)據(jù)表分月存儲(chǔ),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03使用SpringMVC響應(yīng)json格式返回的結(jié)果類型
這篇文章主要介紹了使用SpringMVC響應(yīng)json格式返回的結(jié)果類型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot初始教程之Servlet、Filter、Listener配置詳解
本篇文章主要介紹了SpringBoot初始教程之Servlet、Filter、Listener配置詳解,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09Java模擬QQ實(shí)現(xiàn)聊天互動(dòng)程序
這篇文章主要介紹了如何利用Java語言模擬QQ實(shí)現(xiàn)一個(gè)簡易的聊天互動(dòng)程序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-06-06