通告:个人博客迁往 https://www.cnblogs.com/xsl-thumb-rfcs
Java HashMap遍历过程中如果元素被修改会导致遍历失败,ConcurrentHashMap则不会有这个问题。由此引出HashMap的fast-fail机制和ConcurrentHashMap的的fail-safe机制。

看如下实例。
首先看HashMap的fast-fail

package com;import java.util.HashMap;
import java.util.Map;public class TestHashMapFastFail
{public static void main(String[] args){System.out.println("test HashMap fast-fail");Map<Integer, String> testHashMap = new HashMap<Integer, String>();testHashMap.put(1000, "1000");testHashMap.put(2000, "2000");testHashMap.put(3000, "3000");testHashMap.put(4000, "4000");testHashMap.put(5000, "5000");System.out.println(testHashMap.size());for (Map.Entry<Integer, String> entry : testHashMap.entrySet()){int key = entry.getKey();System.out.println("key=" + key);if (key == 3000){testHashMap.remove(key);}}System.out.println(testHashMap.size());for (Map.Entry<Integer, String> entry : testHashMap.entrySet()){System.out.println(entry.getKey() + "-->" + entry.getValue());}}
}

运行结果

test HashMap
5
key=2000
key=4000
key=1000
key=3000
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)at java.util.HashMap$EntryIterator.next(HashMap.java:1471)at java.util.HashMap$EntryIterator.next(HashMap.java:1469)at com.TestHashMapFastFail.main(TestHashMapFastFail.java:18)

可以看到执行remove操作后,下一轮迭代立刻失效,并抛出异常,这就是所谓的fast-fail。

再看ConcurrentHashMap的fail-safe

package com;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class TestConcurrentHashMapFailSafe
{public static void main(String[] args){System.out.println("test ConcurrentHashMap fast-fail");Map<Integer, String> testConcurrentHashMap = new ConcurrentHashMap<Integer, String>();testConcurrentHashMap.put(100, "100");testConcurrentHashMap.put(200, "200");testConcurrentHashMap.put(300, "300");testConcurrentHashMap.put(400, "400");testConcurrentHashMap.put(500, "500");System.out.println(testConcurrentHashMap.size());for (Map.Entry<Integer, String> entry : testConcurrentHashMap.entrySet()){int key = entry.getKey();System.out.println("key=" + key);if (key == 300){testConcurrentHashMap.remove(key);}}System.out.println(testConcurrentHashMap.size());for (Map.Entry<Integer, String> entry : testConcurrentHashMap.entrySet()){System.out.println(entry.getKey() + "-->" + entry.getValue());}}
}

运行结果

 test ConcurrentHashMap fast-fail
5
key=400
key=100
key=500
key=200
key=300
3
100-->100
500-->500
300-->300

可以看出,尽管在迭代过程中执行了remove操作,但是ConcurrentHashMap对外的表现仍然正常,这就是所谓的fail-safe。原因在于ConcurrentHashMap返回的迭代器是弱一致性,ConcurrentHashMap底层数据结构改变时并且不会抛出ConcurrentModificationException异常。
所以,这也是选择ConcurrentHashMap可以获得的一个额外好处,或者说是解决HashMap fast-fail的一种方法,还有一个方法就是使用迭代器的remove方法而不是使用集合的remove方法,示例如下。

package com;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;public class TestHashMapFastFail2
{public static void main(String[] args){System.out.println("test solve HashMap fast-fail");Map<Integer, String> testHashMap = new HashMap<Integer, String>();testHashMap.put(1000, "1000");testHashMap.put(2000, "2000");testHashMap.put(3000, "3000");testHashMap.put(4000, "4000");testHashMap.put(5000, "5000");System.out.println(testHashMap.size());Iterator iterator = testHashMap.entrySet().iterator();while (iterator.hasNext()){int key = (int)((Map.Entry)iterator.next()).getKey();System.out.println("key=" + key);if (key == 2000 || key == 4000){iterator.remove();}}System.out.println(testHashMap.size());for (Map.Entry<Integer, String> entry : testHashMap.entrySet()){System.out.println(entry.getKey() + "-->" + entry.getValue());}}
}

运行结果

test solve HashMap fast-fail
5
key=2000
key=4000
key=1000
key=3000
key=5000
3
1000-->1000
3000-->3000
5000-->5000

集合的 fast-fail 问题是初学者很容易犯的错误。
说说fast-fail机制和fail-safe机制设计的原因。有人可能会问,既然fast-fail有这么多弊端,为什么还要设计呢,以HashMap为例,因为HashMap本身就是设计成线程不安全的,不支持多个线程同时安全修改,但这也意味着HashMap有较快的速度。fail-safe机制设计的初衷就是保证多线程并发安全地修改集合或Map类。当然,本文的用例都是单线程中的修改操作,主要是为了引出这2个概念。

HashMap的fast-fail和ConcurrentHashMap的fail-safe实例相关推荐

  1. 非线程安全的HashMap 和 线程安全的ConcurrentHashMap

    在平时开发中,我们经常采用HashMap来作为本地缓存的一种实现方式,将一些如系统变量等数据量比较少的参数保存在HashMap中,并将其作为单例类的一个属性.在系统运行中,使用到这些缓存数据,都可以直 ...

  2. P5357 【模板】AC自动机(二次加强版)(AC自动机建fail树dfs求模式串出现次数)

    P5357 [模板]AC自动机(二次加强版)(AC自动机建fail树dfs求模式串出现次数) 传送门 形式上,AC 自动机基于由若干模式串构成的 Trie 树,并在此之上增加了一些 fail 边:本质 ...

  3. Java7/8 中的 HashMap 和 ConcurrentHashMap

    Java7 HashMap  数组+链表 Java7 ConcurrentHashMap   Segment数组+HashEntry数组链表+ReenTrantLock分段锁 Java8 HashMa ...

  4. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2545  Solved: 1419 [Submit][S ...

  5. 【BZOJ4231】回忆树 离线+fail树+KMP

    [BZOJ4231]回忆树 Description 回忆树是树. 具体来说,是n个点n-1条边的无向连通图,点标号为1~n,每条边上有一个字符(出于简化目的,我们认为只有小写字母). 对一棵回忆树来说 ...

  6. ConcurrentHashMap,一个更快的HashMap

    ConcurrentHashMap 是 Doug Lea 的 util.concurrent 包的一部分,它提供比 Hashtable 或者 synchronizedMap 更高程度的并发性.而且,对 ...

  7. HashMap和ConcurrentHashMap的区别,HashMap的底层源码。

    Hashmap本质是数组加链表.根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap:在hashMap的基 ...

  8. 【重难点】【Java集合 01】HashMap 和 ConcurrentHashMap

    [重难点][Java集合 01]HashMap 文章目录 [重难点][Java集合 01]HashMap 一.HashMap 1.概述 2.JDK 1.8 中的变化 3.链表转换为红黑树 4.扩容问题 ...

  9. HashMap及ConcurrentHashMap基本原理概述

    0.前言 本博文部分文字及图片参考自以下三篇文章,其余内容为本人经过思考及总结后所写,仅作为学习分享使用,如有侵权,请联系本人删除,谢谢. 1.什么是HashMap 2.高并发下的HashMap 3. ...

  10. HashMap——ConcurrentHashMap

    HashMap--ConcurrentHashMap 姚博文 文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/java/ ...

最新文章

  1. 综述:目标检测二十年
  2. matlab p-tite分割图像,P'tite fourmi
  3. 廖雪峰python2.7教程_Python 2.7教程
  4. C语言计数排序Counting sort 算法(附完整源码)
  5. javascript获取url参数的代码
  6. 21 个非常有用的 .htaccess 提示和技巧
  7. [webpack3.8.1]Guides-4-Output Management(输出管理)
  8. 斯坦福计算机录取难吗,申请斯坦福究竟有多难? 什么样条件的人才能被斯坦福录取?斯坦福大学直播!...
  9. flink 1.9.0 编译:flink-shaded-hadoop-2 找不到
  10. android面试经典,Android经典面试题集锦(一)
  11. JAVA排序:快速排序算法
  12. php adodb 统计,php之adodb简介
  13. ArcGIS遇到严重的应用程序错误的解决办法
  14. 如何改变计算机内存配置文件,电脑内存使用率过高怎么解决?教你如何调整内存大小...
  15. 苹果照片未删却不见了_手机删除的照片如何恢复?不得不说这方法好!
  16. linux 原型软件,7款免费原型设计工具,总有一款是你的菜!
  17. 电机控制器功率电路MOS管及驱动芯片选型若干问题总结
  18. 功能性测试用例设计方法深入理解
  19. 微信开放平台-第三方平台-全网发布接入【java版本】
  20. 全志A33移植openharmony3.1标准系统之添加产品编译

热门文章

  1. windows10小技巧: 将手机投影到windows10上
  2. 串行通信基础、串行数据传输方式
  3. 【TensorFlow基础操作笔记】图+对话+张量+变量+线性回归实例
  4. 2020-05-13
  5. Cesium奇幻之旅(一)
  6. 2022年京东双11和天猫双11预售时间介绍
  7. PPT制作技巧汇总之图形对象与多媒体应用(office 2007)
  8. 告诉你怎么编写一个最简单的单片机程序
  9. Java两个网页之间的文件互传_如何让两台 PC 进行文件传输?
  10. 如何升级pycharm 中pip的版本