首页
学习
活动
专区
工具
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)条件不成立,抛出异常。 其实质是迭代器设计模式:单线程环境下,如果使用迭代器遍历容器中的元素,必须使用迭代器删除容器中的元素。

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

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值进行删除,很有可能出现“删不掉”的情况。

94430

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

87121

语言小知识-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 不允许为

52610

Java】已解决java.lang.NullPointerException异常

一、问题背景 在Java编程中,java.lang.NullPointerException(空指针异常)是一种常见的运行时异常。当应用程序试图在需要对象的地方使用null时,就会抛出这个异常。...String[] args) { Example example = new Example(); example.printMessage(); // 这里将抛出...NullPointerException } } 在这个例子中,message字段在printMessage方法被调用前没有被初始化,因此尝试调用toUpperCase()方法时会抛出NullPointerException...避免链式调用:当对象可能为null时,避免进行链式调用,因为这可能会导致在调用链中较早的位置抛出NullPointerException。...使用Optional:在Java 8及更高版本中,可以使用Optional来更好地处理可能为null的值。

18710

如何避免 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++这个操作是非原子性的,必然不是线程安全的,说这一点就够了。

38630

Java 捕获和抛出异常

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

1.9K30

Java 14 :NullPointerException的处理新方式

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

1.1K30
领券