原文地址:http://www.journaldev.com/122/java-concurrenthashmap-example-iterator#comment-27448

Today we will look into Java ConcurrentHashMap Example. If you are a Java Developer, I am sure that you must be aware of ConcurrentModificationException that comes when you want to modify the Collection object while using iterator to go through with all its element. Actually Java Collection Framework iterator is great example of iterator design pattern implementation.

Java ConcurrentHashMap

Java 1.5 has introduced java.util.concurrent package with Collection classes implementations that allow you to modify your collection objects at runtime.

ConcurrentHashMap Example

ConcurrentHashMap is the class that is similar to HashMap but works fine when you try to modify your map at runtime.

Lets run a sample program to explore this:

ConcurrentHashMapExample.java

package com.journaldev.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapExample { public static void main(String[] args) { //ConcurrentHashMap
Map<String,String> myMap = new ConcurrentHashMap<String,String>();
myMap.put("1", "1");
myMap.put("2", "1");
myMap.put("3", "1");
myMap.put("4", "1");
myMap.put("5", "1");
myMap.put("6", "1");
System.out.println("ConcurrentHashMap before iterator: "+myMap);
Iterator<String> it = myMap.keySet().iterator(); while(it.hasNext()){
String key = it.next();
if(key.equals("3")) myMap.put(key+"new", "new3");
}
System.out.println("ConcurrentHashMap after iterator: "+myMap); //HashMap
myMap = new HashMap<String,String>();
myMap.put("1", "1");
myMap.put("2", "1");
myMap.put("3", "1");
myMap.put("4", "1");
myMap.put("5", "1");
myMap.put("6", "1");
System.out.println("HashMap before iterator: "+myMap);
Iterator<String> it1 = myMap.keySet().iterator(); while(it1.hasNext()){
String key = it1.next();
if(key.equals("3")) myMap.put(key+"new", "new3");
}
System.out.println("HashMap after iterator: "+myMap);
} }

When we try to run the above class, output is

ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
at java.util.HashMap$KeyIterator.next(HashMap.java:828)
at com.test.ConcurrentHashMapExample.main(ConcurrentHashMapExample.java:44)

Looking at the output, its clear that ConcurrentHashMap takes care of any new entry in the map whereas HashMap throws ConcurrentModificationException.

Lets look at the exception stack trace closely. The statement that has thrown Exception is:

String key = it1.next();

It means that the new entry got inserted in the HashMap but Iterator is failing. Actually Iterator on Collection objects are fail-fast i.e any modification in the structure or the number of entry in the collection object will trigger this exception thrown by iterator.

So How does iterator knows that there has been some modification in the HashMap. We have taken the set of keys from HashMap once and then iterating over it.

HashMap contains a variable to count the number of modifications and iterator use it when you call its next() function to get the next entry.

HashMap.java

/**
* The number of times this HashMap has been structurally modified
* Structural modifications are those that change the number of mappings in
* the HashMap or otherwise modify its internal structure (e.g.,
* rehash). This field is used to make iterators on Collection-views of
* the HashMap fail-fast. (See ConcurrentModificationException).
*/
transient volatile int modCount;

Now to prove above point, lets change the code a little bit to come out of the iterator loop when we insert the new entry. All we need to do is add a break statement after the put call.

if(key.equals("3")){
myMap.put(key+"new", "new3");
break;
}

Now execute the modified code and the output will be:

ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
HashMap after iterator: {3=1, 2=1, 1=1, 3new=new3, 6=1, 5=1, 4=1}

Finally, what if we won’t add a new entry but update the existing key-value pair. Will it throw exception?

Change the code in the original program and check yourself.

//myMap.put(key+"new", "new3");
myMap.put(key, "new3");

If you get confused (or shocked) with the output, comment below and I will be happy to explain it further.

Did you noticed those angle brackets while creating our collection object and Iterator, it’s called generics in java and it’s very powerful when it comes to type-checking at compile time to remove ClassCastException at runtime, learn more about generics in Java Generics Example.

Java ConcurrentHashMap Example and Iterator--转的更多相关文章

  1. Java ConcurrentHashMap

    通过分析Hashtable就知道,synchronized是针对整张Hash表的,即每次锁住整张表让线程独占, ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术. ...

  2. java基础-迭代器(Iterator)与增强for循环

    java基础-迭代器(Iterator)与增强for循环 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Iterator迭代器概述 Java中提供了很多个集合,它们在存储元素时 ...

  3. Java ConcurrentHashMap 源代码分析

    Java ConcurrentHashMap jdk1.8 之前用到过这个,但是一直不清楚原理,今天抽空看了一下代码 但是由于我一直在使用java8,试了半天,暂时还没复现过put死循环的bug 查了 ...

  4. java:集合输出之Iterator和ListIterator二

    java:集合输出之Iterator和ListIterator二 ListIterator是Iterator的子接口,Iterator的最大特点是,能向前,或向后迭代.如果现在要想双向输出的话,则只能 ...

  5. Java - ConcurrentHashMap的原理

    Java - ConcurrentHashMap的原理 **这是JDK1.7的实现** ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment. HashE ...

  6. HashMap vs ConcurrentHashMap — 示例及Iterator探秘

    如果你是一名Java开发人员,我能够确定你肯定知道ConcurrentModificationException,它是在使用迭代器遍历集合对象时修改集合对象造成的(并发修改)异常.实际上,Java的集 ...

  7. JAVA中ListIterator和Iterator详解与辨析

    在使用Java集 合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator,在使用List.ArrayList. LinkedList和Vector的时候可以使用 ...

  8. Java API ——Collection集合类 & Iterator接口

    对象数组举例: 学生类: package itcast01; /** * Created by gao on 15-12-9. */ public class Student { private St ...

  9. Java ConcurrentHashmap 解析

    总体描述: concurrentHashmap是为了高并发而实现,内部采用分离锁的设计,有效地避开了热点访问.而对于每个分段,ConcurrentHashmap采用final和内存可见修饰符Volat ...

随机推荐

  1. Essential controls for web app

    AUTO-COMPLETE/AUTO-SUGGEST Auto-complete using Vaadin Offer auto-suggest or auto-complete to help yo ...

  2. angularjs 解决ng-repeat数组内重复对象报错的问题

    ng-repeat 循环数组内元素时,如果数组内元素重复,angular会抛出异常: Error: [ngRepeat:dupes] http://errors.angularjs.org/1.4.3 ...

  3. jquery mobile 问问多多

    jquery mobile  问题多多,兼容性太差.android4.1下完全崩溃.以后再也不用jquery mobile了

  4. MyEclipse新建web project和navicat110_mysql_en工具

    首先注意几点: 1.eclipse web项目:项目名称不得超过五个字符,要求全部小写,不管变量名.类名.函数名.文件名,在没有特殊理由的时候,不要用下划线,同时表名和类名用两个单词,尽量不要用Stu ...

  5. CSS 背景属性

    background: 简写属性,作用是将背景属性置在一个声明中 background-attachment: 背景图像是否固定或者随着页面的其余部队滚动 background-color: 设置元素 ...

  6. CocoaPods pod install

    加参数可以提升更新的速度 方法1: pod install --verbose --no-repo-update pod update --verbose --no-repo-update 方法2: ...

  7. MongoDB 初见指南

    技术若只如初见,那么还会踩坑么? 在系统引入 MongoDB 也有几年了,一开始是因为 MySQL 中有单表记录增长太快(每天几千万条吧)容易拖慢 MySQL 的主从复制.而这类数据增长迅速的流水表, ...

  8. 我的面板我做主 -- 淘宝UWP中自定义Panel的实现

    在Windows10 UWP开发平台上内置的XMAL布局面板包括RelativePanel.StackPanel.Grid.VariableSizedWrapGrid 和 Canvas.在开发淘宝UW ...

  9. iOS开发系列--视图切换

    概述 在iOS开发中视图的切换是很频繁的,独立的视图应用在实际开发过程中并不常见,除非你的应用足够简单.在iOS开发中常用的视图切换有三种,今天我们将一一介绍: UITabBarController ...

  10. [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

    [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...