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不存在返回nullgetOrDefault()
- 获取指定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}
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
java并发编程工具类JUC第八篇:ConcurrentHashMap的更多相关文章
- java并发编程工具类JUC第四篇:LinkedBlockingQueue链表队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue. LinkedBlockingQueue 队列是Blo ...
- java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- java并发编程工具类JUC第三篇:DelayQueue延时队列
DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的"延时时间"进行排序).另一层 ...
- java并发编程工具类JUC第一篇:BlockingQueue阻塞队列
Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...
- java并发编程工具类JUC第二篇:ArrayBlockingQueue
类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- java并发编程工具类辅助类:CountDownLatch、CyclicBarrier和 Semaphore
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...
- java并发编程笔记(十)——HashMap与ConcurrentHashMap
java并发编程笔记(十)--HashMap与ConcurrentHashMap HashMap参数 有两个参数影响他的性能 初始容量(默认为16) 加载因子(默认是0.75) HashMap寻址方式 ...
- Java并发编程入门,看这一篇就够了
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容.这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉 ...
随机推荐
- Portswigger web security academy:SQL injection
Portswigger web security academy:SQL injection 目录 Portswigger web security academy:SQL injection SQL ...
- linux 查看运行java所在目录
通过ps及top命令查看进程信息时,只能查到相对路径,查不到的进程的详细信息 需要查看pos_service.jar的绝对路径(在哪里目录下) 使用:ll /proc/PID Linux在启动一个进 ...
- Hive解析Json数组超全讲解
在Hive中会有很多数据是用Json格式来存储的,如开发人员对APP上的页面进行埋点时,会将多个字段存放在一个json数组中,因此数据平台调用数据时,要对埋点数据进行解析.接下来就聊聊Hive中是如何 ...
- 一个入门级CTF的Reverse
这道题是XCTF攻防世界上的一道新手入门题目! 年前刚接触逆向时IDA,OD了这些工具都不会用(负基础),当时做这些题的时候觉得挺难(主要是缺少练习,没思路无从下手).现在回头再来看这些题目感觉确实是 ...
- Solon 的过滤器 Filter 和两种拦截器 Handler、 Interceptor
在web开发中,过滤器.拦截器是经常用到的功能.它可以帮我们限制流量.验证是否登陆.记录日志以及统计执行效率等等. 今天主要交流一下 Solon 框架中的过滤器和拦截器. Solon 是什么框架? S ...
- [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]
[网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...
- HUGO 创建属于自己的博客
Hugo 拥有超快的速度,强大的内容管理和强大的模板语言,使其非常适合各种静态网站.可以轻松安装在macOS,Linux,Windows等平台上,在开发过程中使用LiveReload可即时渲染更改 一 ...
- 最全的cURL命令使用
cURL是什么 curl是Linux命令行工具,可以使用任何可支持的协议(如HTTP.FTP.IMAP.POP3.SCP.SFTP.SMTP.TFTP.TELNET.LDAP或FILE)在服务器之间传 ...
- Shell $?获取函数返回值或者上一个命令的退出状态
Shell $?获取函数返回值或者上一个命令的退出状态 来自:互联网 时间:2021-01-12 阅读:2 $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值. 所谓退出状态, ...
- CentOS7配置kdump
CentOS7配置kdump 简单生活,简单爱 2020-10-27 16:29:56 56 收藏 1 分类专栏: Linux实际开发总结 版权 文章目录 1.kdump简介 2.配置kdump ...