代码如下

    /**
* 测试ConcurrentHashMap null键和null值的问题
* @return
*/
@RequestMapping(value = "/get_nacos")
public String getNacos(){
ConcurrentHashMap<String,String> map =new ConcurrentHashMap<>(1);
map.put("testKey", null);
String nullValue = map.get("sss");
return nullValue;
}
}

其中在执行put操作时,会报错,信息如下:

java.lang.NullPointerException: null
at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011) ~[na:1.8.0_162]
at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006) ~[na:1.8.0_162]
at com.gabriel.stage.controller.TestController.getNacos(TestController.java:44) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]

那么这里就有一个疑问了,为什么HashMap能存null键和null值,ConcurrentHashMap就不能存null键和null值了呢,并且还会出现空指针异常

个人理解如下:

  ConrrentHashMap 是一个用于多线程并发场景下的并发容器(Map),也就是在多线程环境下执行增删改查方法要保证线程安全性,

  例如containsKey()方法中

    public boolean containsKey(Object key) {
return get(key) != null;
}

  该方法会调用get方法去查询key值是否存在,此时如果key值是我们手动存进去的,这个时候就会在代码语义上有区别,无法区分是真的没有该key 还是我们存储的key,

  并且在调用get()方法时,可能会出现别的线程修改为null键和null值的情况,这中情况在并发场景下会产生歧义;

  

 HashMap本身是一个线程不安全的容器(Map),也就是使用场景局限于单线程环境,因此存储null键null值 通常不会有什么问题,

 HashMap将存储的null键存储到数组的第1个元素;

【Java基础】ConcurrentHashMap为什么不能存null键和null值的更多相关文章

  1. Java基础-SSM之mybatis一对一外键关联

    Java基础-SSM之mybatis一对一外键关联 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.准备测试环境(创建数据库表)  1>.创建husbandsfk和wife ...

  2. 【Java基础】基本类型的包装类作为参数传递是值传递还是引用传递

    突然想到这个问题,然后做了下实验,下面以Integer来讲解,其他的忽略: import java.util.Iterator; /** * Created by lili on 15/9/24. * ...

  3. java基础之抽象类与接口的形式参数和返回值

    抽象类与接口形式参数和返回值问题 1.形参问题 /* 1.形式参数: 基本类型(太简单,不是我今天要讲解的) 引用类型 (1)类名:(匿名对象的时候其实我们已经讲过了) 需要的是该类的对象 (2)抽象 ...

  4. java基础 (二)之HashMap,HashTable,ConcurrentHashMap区别

    HashTable: put方法加了同步锁synchronized,底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable, ...

  5. Java基础系列--HashMap(JDK1.8)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...

  6. BAT常问问题总结以及回答(java基础回答一)

    java 基础 八种基本数据类型的大小,以及他们的封装类  答:八种数据类型分别是byte(1字节)-128~127.short(2字节)-32768~32767.char(2字节).int(4字节) ...

  7. [Java面试二]Java基础知识精华部分.

    一:java概述(快速浏览): 1991 年Sun公司的James Gosling等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒.PDA等的微处理器: 1994年将Oak语言更名 ...

  8. Java基础知识总结【转+整合】

    写代码: 1.明确需求.自己要做什么? 2.分析思路.怎么做? 3.确定步骤.每个思路部分用到哪些语句,方法和对象. 4.代码实现.用具体的java语言代码把思路体现出来. 学习新技术的四点: 1,该 ...

  9. Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

随机推荐

  1. 后端程序员之路 12、K最近邻(k-Nearest Neighbour,KNN)分类算法

    K最近邻(k-Nearest Neighbour,KNN)分类算法,是最简单的机器学习算法之一.由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重 ...

  2. C语言中指针和多维数组

    指针和多维数组 数组名是特殊的指针 数组是一个特殊的指针,多维数组也是更为复杂的数组,它们的关系是什么样的呢? 我们通过一个简单的例子来比较形象的了解指针和多维数组: int a[2][3]; 这是一 ...

  3. PHP题库1

    选择题11. php中,不等运算符是( B.C ) A ≠    B !=   C <>   D >< 2. 函数的参数传递包括:( A.B ) A 按值传递       B ...

  4. Linux发行版及其目标用户

    1.Debian Debian 众所周知,是Deepin,Ubuntu和Mint等流行Linux发行版的母亲,这些发行版提供了可靠的性能,稳定性和无与伦比的用户体验.最新的稳定发行版是Debian 1 ...

  5. jdk8的安装与环境搭建

    jdk8的安装与环境搭建 jdk8下载网址:https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html ...

  6. 超详细Linux新手快速入门(一)——Linux的介绍安装以及虚拟机的介绍安装

    一.Linux的介绍 1.Linux和Windows的比较  Linux是一款操作系统,其性能稳定,因其防火墙组件高效安全.简单易配置,所以获得了追求速度和安全的一些企业和人群的青睐.与我们日常所熟知 ...

  7. javascript 之对象-13

    对象 无序属性的集合,属性可以包含基本值.对象或者函数,简单理解为对象是若干属性的集合:我们常说的面向对象(oop)编程其实是指的一种编码的思想,简单理解为用对象来封装数据,利用封装.继承.多态对代码 ...

  8. MySQL入门(2)——存储引擎

    MySQL入门(2)--存储引擎 查询MySQL支持的存储引擎 查询全部支持的引擎: show engines; ";"可以使用"\g"等价替换,而使用&quo ...

  9. Codeforces Round #537 C. Creative Snap

    题面: 传送门 题目描述: 灭霸想要摧毁复仇者联盟的基地.基地的长度为2的n次方,基地可以看成是一个长度为2的n次方的数组.基地的每一个位置可以由很多个超级英雄,但是一个超级英雄只能站一个位置.灭霸想 ...

  10. Java8的新特性--并行流与串行流

    目录 写在前面 Fork/Join框架 Fork/Join框架与传统线程池的区别 传统的线程池 Fork/Join框架 Fork/Join框架的使用 Java8中的并行流 写在前面 我们都知道,在开发 ...