首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

java陷阱之:HashMap for each遍历同时删除,抛出ConcurrentModificationException

---- 现象 ---- 当HashMap使用for each遍历entrySet的同时,使用HashMap的remove操作元素时,并不是在并发的情况下,也会抛出异常:ConcurrentModificationException...at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1597) at java.base/java.util.HashMap...$EntryIterator.next(HashMap.java:1630) at java.base/java.util.HashMap$EntryIterator.next(HashMap.java...,而删除元素使用的java.util.HashMap#remove(java.lang.Object)方法是HashMap的,并不是迭代器的方法。...= expectedModCount)条件不成立,抛出异常。 其实质是迭代器设计模式:单线程环境下,如果使用迭代器遍历容器中的元素,必须使用迭代器删除容器中的元素。

33220
您找到你想要的搜索结果了吗?
是的
没有找到

Java集合中的HashMap

HashMap中定义了一个size变量,再此处直接返回size变量而不用调用entrySet方法返回集合再计算。可以猜测这个size变量是当插入一个key-value键值对的时候自增。...在迭代器初始化过程会将modCount赋给迭代器的ExpectedModCount,是否会抛出ConcurrentModificationException异常的实现就是在迭代过程中判断modCount...此时线程T1对扩容前的HashMap元素已经完成了转移,但由于Java内存模型的缘故线程T2此时看到的还是它自己线程中HashMap之前的变量副本。此时T2对数据进行转移,如下图所示。 ?   ...所以,千万不要使用在并发环境下使用HashMap,一旦出现死循环CPU100%,这个问题不容易复现及排查。并发环境一定需要使用ConcurrentHashMap线程安全。   ...这个方法容易陷入的陷阱是key值是一个自定义的pojo,且并没有重写equals和hashCode方法,此时用pojo作为key值进行删除,很有可能出现“删不掉”的情况。

92630

Java-抛出异常、自定义异常

但这种错误一般是偶然的,可能是用户输入不呵呵程序编写者的意图导致,而不是程序本身问题,这是我们要做的,是让操作者知道发生了什么事情,而不是直截了当的结束程序,这时我们就用到了异常处理(语句发生错误时,只抛出异常...但是在写完throw/throws 语句后,异常处理并没有结束,因为这里只是简单声明了,我的这个成员方法中的可能会抛出异常,并没有写具体该如何处理这个异常,所以这是在主函数中,就要用try()catch...自定义异常是逃不开,也是新手接触最少的,其实它的基本使用方法还是很简单的,自定义异常处理,只包括两部分:(1)、的构造方法,构造方法的建立则非常简单,其实只要继承父(比如 Exception...(2)、重写toString()函数,这是最重要的一点,再toString函数中,描述具体发生了什么错误导致了异常的抛出。...+1可见 该测试一定越界 textArray[j] = 5 ;//给数组原属赋值 } } } 如上图所示,如果发生了异常,这才catch()语句中声称自定义的异常对象,并输出具体信息: java

1.3K20

JavaNullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ArrayIndexOutOfBoundsE

今天工作中,临时Fix一个bug,一看日志“java.lang.ClassCastException: null” 相当懵逼,没有详细堆栈信息,这咋整。...当第一次发生异常(通常为NullPointerException)时,将打印完整的堆栈跟踪,并且JVM会记住堆栈跟踪(或者可能只是代码的位置)。...当该异常经常发生时,将不再打印堆栈跟踪,这既可以实现更好的性能,【CoederBaby】又不会使相同的堆栈跟踪充满日志 【进一步分析】 参看JVM源码(参见附录2),可见这个优化同时试用于以下异常: NullPointerException...break; default: break; } 参考: stackoverflow : https://stackoverflow.com/questions/2411487/nullpointerexception-in-java-with-no-stacktrace...相关JVM源码:https://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/opto/graphKit.cpp

84321

语言小知识-Java HashMap 深度解析

HashMap 也是比较常用的 Java 集合框架,该类涉及到的知识比较多,包括数组、链表、红黑树等等,还有一些高效巧妙的计算,并且这个类经过几个版本的改进,不同版本之间是有些差异的,这里都是基于 JDK8...问题 2:HashMap 内部是怎么存放数据的? ?...问题 3:HashMap 扩容的方法? 当 HashMap 中的 size >= threshold 时,HashMap 就要扩容。...并且 HashMap 扩容时,table 数组的长度是原来的两倍,还是 2 的次幂,始终可以很快地计算 Node 在数组中的位置 index。 问题 6:几种 Map 集合的对比?...Map 集合 key value Super JDK 说明 Hashtable 不允许为 null 不允许为 null Dictionary 1.0 线程安全(过时) ConcurrentMap 不允许为

51710

如何避免 Java 中的“NullPointerException

1 最常见的异常 NullPointerException (NPE) 是 Java 中最常见的异常。此异常的原因是已知的,但在大多数情况下,开发人员更愿意忽略它并且不采取任何措施。...Java 提供了编译类型安全,它向开发人员保证他不能不匹配不同的变量类型。而且,如果您这样做了 - Java 甚至会在编译步骤中让他知道。...但是,一旦我们运行这个程序,它将失败并出现 NullPointerException: 空指针异常 5 NullPointerException 定义 NullPointerException 是一个运行时异常...7 NullPointerException 在我们的示例中,我们有一个带有地址字段的用户对象。潜在地,它们都可能为空。让我们看看如何避免 NullPointerException。...让我们创建一个简单的,其中包含两个字段,其中一个是我们标记为@NonNull 的字段: 具有两个字段的简单 Checker Framework 会接受此代码吗?

2.8K20

一文读懂JAVA并发容器HashMap

今天一起说说并发容器,实际上还是JDK代码里面的东西,其实不管是Map或者ConcurrentMap,网上太多的资料了,其实有些资料也是从网上找的,但是加入了自己的理解,更易懂的方式展示给的大家,技术点老铁们都是可以看懂的...如果JAVA中网络编程只提供了BIO和NIO两种方式,所以一切框架中,涉及到网络处理的,都可以用这两个知识点去探究原理。万丈高楼平地起,盖房子都是从下往上的,学习知识也是一样。...(二)推理HashMap的实现 ① 介绍 HashMap就是往里面存东西,存放的方式就是键值对的概念。key用来查找。 *② 考虑存储的介质 数据存储分为:链表,树,队列,图。。。...具体HashMap呢,看看源码 ?...⑤ HashMap的总结 数组的大小一定是2的N次方。 为什么HashMap是线程非安全的,其实就一点,扩容的时候链表进行i++,i++这个操作是非原子性的,必然不是线程安全的,说这一点就够了。

37830

Java 捕获和抛出异常

参考链接: Java捕获多个异常 Java中把非正常情况分为两种:异常(Exception)和错误(Error),其中Error错误一般是指与虚拟机相关的问题,这种错误无法恢复或不可能捕获,而对于Exception...Java7后支持用catch捕获多个异常,也可捕获自定义异常。对于捕获的异常一般可以使用printStackTrace()方法追踪输出至标准错误流。...代码示例如下   除捕获异常以外可以使用throws将异常进行抛出抛出的异常由上级调用者处理,上级调用者可以进行处理或抛出异常,上级调用者可以抛出更广泛的异常。...JVM将打印异常的跟踪栈信息,并中止程序运行,示例如下  除了使用throws抛出异常外也可以使用throw自行抛出异常。...throw语句可以单独使用, throw语句抛出的不是异常,而是一个异常实例,而且每次只能抛出一个异常实例。

1.9K30

JDK1.8源码(七)——java.util.HashMap

JDK 还为我们提供了一个抽象 AbstractMap ,该抽象继承 Map 接口,所以如果我们不想实现所有的 Map 接口方法,就可以选择继承抽象 AbstractMap 。...但是我们发现 HashMap 即继承了 AbstractMap 接口,也实现了 Map 接口,这样做难道不是多此一举?后面我们会讲的 LinkedHashSet 集合也有这样的写法。...据 java 集合框架的创始人Josh Bloch描述,这样的写法是一个失误。...在java集合框架中,类似这样的写法很多,最开始写java集合框架的时候,他认为这样写,在某些地方可能是有价值的,直到他意识到错了。...(int initialCapacity, float loadFactor) { 7 //初始化容量不能小于 0 ,否则抛出异常 8 if (initialCapacity

85660

Java 14 :NullPointerException的处理新方式

最近新出的Java14,相信大家都有所耳闻,那么今天就来看看,面对NullPointerExceptionJava14有哪些更好的处理方式呢?...首先,只有当JVM本身抛出一个 NullPointerException 时,才会进行详细的消息计算,如果我们在Java代码中显式抛出异常,则不会执行计算。...因此,对于通常的JVM流程不应该有任何性能影响,在那里我们可以捕获并重新抛出异常,因为咱并不会只想打印异常消息。 最后,详细的异常消息可能包含源代码中的局部变量名。...但是,只有在运行使用激活的 -g 标记编译的代码时,才会发生这种情况,该标记会生成调试信息并将其添加到文件中。...关于NullPointerException的处理到这里就结束了,通过Java14增强的NullPointerException,我们可以很快速的定位代码问题的原因所在,更快的调试代码,节约时间,提高效率

1K30

Java编程进阶之路 01】深入探索:HashMap、ConcurrentHashMap与HashTable的演进之路

HashMap、ConcurrentHashMap和HashTable都是Java集合框架中的哈希表实现,但它们在多个方面存在显著的区别。从线程安全性到性能表现,再到内部实现机制,这三个各有千秋。...02 继承的父 HashMap, ConcurrentHashMap, 和 HashTable 都是实现了 Map 接口的,用于存储键值对。...下面是这三个在继承和实现方面的主要区别: 2.1 HashMap继承自AbstractMap 继承与实现:HashMap 继承自 AbstractMap 并实现了 Map, Cloneable,...如果尝试这样做,将会抛出NullPointerException。这是HashTable的一个严格限制,与HashMap和ConcurrentHashMap不同。...如果尝试使用null作为键,将会抛出NullPointerException。然而,如果先插入一个有效的键,然后使用该键来存储null值,这是完全允许的。

12710
领券