原文地址: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. Python实战 :2017国考职业表excel转数据库,再查询生成excel

    最近看2017年国考的职业表,多而杂,不好过滤我想要的信息,特此把它转成Sqlite3数据库,再从数据库里把查询结果导出成excel,方便找职业. (后附上整套代码) 环境:python2.7   x ...

  2. *POJ1830 高斯消元

    开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8010   Accepted: 3161 Description ...

  3. DSY3163*Eden的新背包问题

    Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...

  4. 【转载】在 2016 年做 PHP 开发是一种什么样的体验?(一)

    转自:https://www.v2ex.com/t/312651 在 2016 年做 PHP 开发是一种什么样的体验?(一) 嘿,我最近接到一个网站开发的项目,不过老实说,我这两年没怎么接触编程,听说 ...

  5. 设置DataGridView的某个单元格为ComboBox

    怎么将DataGridView的 某个单元格设为ComboBox的样式而不是整列都改变样式? 1.最简单的方法:利用DataGridView提供的DataGridViewComboBoxCell. 写 ...

  6. 工作总结_JS_1

    获取点击下的相对应的div: $('> div', this).show(); 本身同级下的相对应的div:   $('>div[name=vv]', $(this).siblings(& ...

  7. error C2678

    自定义结构类型,为支持插入到stl set或者排序,一种方式是重载operator<运算符成员函数.如果忘记将函数标识为const,则在编译时会报 6>c:\program files ( ...

  8. PHP基础知识之流程控制的替代语法

    PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch. 替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,e ...

  9. Ring0隐藏进程的方法

    第一种在系统调用服务表HOOK ZwQuerySystemInformation函数地址 使用InterlockedExchange函数将ZwQuerySystemInformation在内核导出表K ...

  10. XML数据的解析

    XML数据的解析 相比于JSON数据解析而言,XML数据解析可能会让更多的童鞋感觉到吃力,对我来说,同样认为JSON数据好像让人感觉比较友好,不过对于程序开发者来说,无非就是这两种数据解析占比较大的部 ...