在之前的文章中已经为大家介绍了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}

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

  • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

java并发编程工具类JUC第八篇:ConcurrentHashMap的更多相关文章

  1. java并发编程工具类JUC第四篇:LinkedBlockingQueue链表队列

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue. LinkedBlockingQueue 队列是Blo ...

  2. java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...

  3. java并发编程工具类JUC第三篇:DelayQueue延时队列

    DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的"延时时间"进行排序).另一层 ...

  4. java并发编程工具类JUC第一篇:BlockingQueue阻塞队列

    Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...

  5. java并发编程工具类JUC第二篇:ArrayBlockingQueue

    类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...

  6. Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

    Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...

  7. java并发编程工具类辅助类:CountDownLatch、CyclicBarrier和 Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...

  8. java并发编程笔记(十)——HashMap与ConcurrentHashMap

    java并发编程笔记(十)--HashMap与ConcurrentHashMap HashMap参数 有两个参数影响他的性能 初始容量(默认为16) 加载因子(默认是0.75) HashMap寻址方式 ...

  9. Java并发编程入门,看这一篇就够了

    Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容.这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉 ...

随机推荐

  1. Linux-鸟菜-0-计算机概论

    Linux-鸟菜-0-计算机概论 这一章在说计算机概论,额....,总的来说看完之后还是有点收获,回忆了下计算机基本知识.没有什么可上手操作的东西,全是概念,直接把最后的总结给截图过来吧,因为概念的话 ...

  2. 【vue-02】基础语法

    插值操作 插值运算符 语法:{{数据}} 插值运算符可以对数据进行显示{{msg}},也可以在插值运算符中进行表达式计算{{cnt*2}}. v-html 希望以html格式进行输出 htmlData ...

  3. Windows bat批处理删除指定N天前的文件

    1:新建批处理文件:del_old_file.bat,更改系统时间为7天前,在c盘sql back 目录下新建测试文件,再将系统时间改为正确时间 2:编辑内容: rem 删除C:\sql back目录 ...

  4. mysql 的查询操作语句---自动生成各种不同的序号

    1.通过查询语句添加自动生成序号 SELECT m.id,(@a :=@a + 1) AS a FROM 表名 m, (SELECT @a := 0) t1 2.MySQL字符串前后补0 前补0(LP ...

  5. 8张图带你了解iptables的前世今生

    1 安全技术和防火墙 1 安全技术和防火墙 入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化.定位来自内 外网络的威胁情况,主要以提供报警和事后监 ...

  6. 多种方法实现实现全排列 + sort调用标准函数库函数的简述

    全排列:所有不同顺序的元素组组成的一个集合.这里使用使用递归实现全排列. 使用递归算算法呢,首先我们先找一下结束的条件:我们要对一组元素(这里使用数字举例)实现全排列,临界条件就是递归到只有一个元素的 ...

  7. Java学习之jackson篇

    Java学习之jackson篇 0x00 前言 本篇内容比较简单,简单记录. 0x01 Json 概述 概述:JSON(JavaScript Object Notation, JS 对象简谱) 是一种 ...

  8. [操作系统知识储备,进程相关概念,开启进程的两种方式、 进程Queue介绍]

    [操作系统知识储备,进程相关概念,开启进程的两种方式.进程Queue介绍] 操作系统知识回顾 为什么要有操作系统. 程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作 ...

  9. 【大白话 mysql】mysql 事务与日志原理

    在后端面试中,mysql是比不可少的一环,其中对事务和日志的考察更是"重灾区", 大部分同学可能都知道mysql通过redolog.binlog和undolog保证了sql的事务性 ...

  10. 二进制部署K8S-2集群部署

    二进制部署K8S-2集群部署 感谢老男孩教育王导的公开视频,文档整理自https://www.yuque.com/duduniao/k8s. 因为在后期运行容器需要有大量的物理硬件资源使用的环境是用的 ...