Java并发编程之详解ConcurrentHashMap类

 更新时间:2021年06月23日 14:39:17   作者:字母哥博客  
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、BlockingDeque接口,本文为系列文章第八篇.需要的朋友可以参考下

Java技术迷

前言

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

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

一、创建ConcurrentHashMap对象

通过下面的代码创建ConcurrentHashMap

1
2
// 创建容量为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

1
ConcurrentHashMap<Key, Value> 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不存在则插入数据,否则不做操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
    }
}

输出结果:

1
2
偶数集合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的集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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不存在返回一个指定的默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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中没有这个键值对。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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并发编程之详解ConcurrentHashMap类的文章就介绍到这了,更多相关Java ConcurrentHashMap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

蓄力AI

微信公众号搜索 “ 脚本之家 ” ,选择关注

程序猿的那些事、送书等活动等着你

原文链接:https://www.cnblogs.com/zimug/p/14892114.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!

相关文章

  • java实现301跳转和重定向的方法

    java实现301跳转和重定向的方法

    301跳转和重定向是做项目的时候经常需要用到的,本文给大家分享的是在java中301跳转和重定向的方法,需要的小伙伴参考下吧。
    2015-03-03
  • Mybatis返回Map对象的实现

    Mybatis返回Map对象的实现

    本文介绍了Mybatis和MybatisPlus在查询数据库时返回Map对象的多种实现方式,这些方法有助于优化DAO层代码,使其更加清晰和高效,下面就来具体介绍一下,感兴趣的可以了解一下
    2024-09-09
  • JavaWeb中获取表单数据及乱码问题的解决方法

    JavaWeb中获取表单数据及乱码问题的解决方法

    这篇文章主要介绍了JavaWeb中获取表单数据及乱码问题的解决方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • idea每次新打开的项目窗口maven都要重新设置问题

    idea每次新打开的项目窗口maven都要重新设置问题

    这篇文章主要介绍了idea每次新打开的项目窗口maven都要重新设置问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • MyBatis实现简单的数据表分月存储

    MyBatis实现简单的数据表分月存储

    本文主要介绍了MyBatis实现简单的数据表分月存储,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 使用SpringMVC响应json格式返回的结果类型

    使用SpringMVC响应json格式返回的结果类型

    这篇文章主要介绍了使用SpringMVC响应json格式返回的结果类型,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • SpringBoot初始教程之Servlet、Filter、Listener配置详解

    SpringBoot初始教程之Servlet、Filter、Listener配置详解

    本篇文章主要介绍了SpringBoot初始教程之Servlet、Filter、Listener配置详解,具有一定的参考价值,有兴趣的可以了解一下
    2017-09-09
  • IDEA maven项目依赖无法解析问题

    IDEA maven项目依赖无法解析问题

    这篇文章主要介绍了IDEA maven项目依赖无法解析问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Json读写本地文件实现代码

    Json读写本地文件实现代码

    今天没事研究了下Gson,写了个工具类,需要的朋友可以参考下
    2014-03-03
  • Java模拟QQ实现聊天互动程序

    Java模拟QQ实现聊天互动程序

    这篇文章主要介绍了如何利用Java语言模拟QQ实现一个简易的聊天互动程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-06-06

最新评论