Java并发编程之详解ConcurrentHashMap类

网友投稿 290 2023-01-04

Java并发编程之详解ConcurrentHashMap类

前言

由于java程序员常用的HashMap的操作方法不是同步的,所以在多线程环境下会导致存取操作数据不一致的问题,Map接口的另一个实现类Hashtable 虽然是线程安全的,但是在多线程下执行效率很低。为了解决这个问题,在java 1.5版本中引入了线程安全的集合类ConcurrentMap。

java.util.concurrent.ConcurrentMap接口是Java集合类框架提供的线程安全的map,这意味着多线程同时访问它,不会影响map中每一条数据的一致性。ConcurrentMap接口有两个实现类ConcurrentHashMap和ConcurrentSkipListMap,经常被使用的是ConcurrentHashMap,我们来重点关注它。

一、创建ConcurrentHashMap对象

通过下面的代码创建ConcurrentHashMap

// 创建容量为8,负载系数为0.6的ConcurrentHashMap

ConcurrentHashMap 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 numbers1 = new ConcurrentHashMap<>();

二、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 evenNumbers = new ConcurrentHashMap<>();

// 使用put()方法插入数据

evenNumbers.put("Two", 2);

evenNumbers.put("Four", 4);

// 使用putIfAbsent()插入数据

evenNumbers.putIfAbsent("Six", 6);

System.out.println("偶数集合ConcurrentHashMap: " + evenNumbers);

//创建ConcurrentHashMap用于保存整数

ConcurrentHashMap 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 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]

ValueHVpcSs: [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 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 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}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot下载Excel文件时,报错文件损坏的解决方案
下一篇:顺风国际快递物流查询单号(顺丰国际快递单号查询官方)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~