从java1.5开始java加入了Doug Lea大神的concurrent包下的代码,看了Doug Lea的代码越看越惊心,真的是太厉害了,神一样的感觉(感叹一下)。

进入正题,ConcurrentHashMap这个类是为了在高并发环境下而创建的代替HashMap散列结构,因此在实现了HashMap功能的基础上加入了分段锁的概念(java1.7包括1.7以前使用Segment继承ReentrantLock的方式实现),与HashTable这类容器相比提高了并发程度,同时避免了HashMap可能产生的线程不安全问题。在了解这些基础知识以后,会有一个问题,既然使用了分段锁,那整个Map的size该如何统计?是没一个segment都上锁统计么?这边先看一下源码:

concurrenHashMap size方法

发现获取全部分段锁来进行size统计是有条件,而不是一开始就进行的,是需要进行RETRIES_BEFORE_LOCK比较判断的,那我们先把这个放一放,看看如何会达成这个条件。

逻辑是这样的:

获取全部分段锁进行size统计之前先尝试不加锁统计

首先遍历HashMap中已有的segments将每个segment的count加起来作为整个hashMap的size,自然能想到那这时候有其他线程修改了segement中的数据让count有变化我怎么办?我并不知道到底有没有被修改啊。这时候不得不佩服大神的思路,他利用modCount和两次比较来实现size的确认。具体过程是:

1.进行第一遍遍历segments数组,将每个segemnt的count加起来作为总数,期间把每个segment的modCount加起来sum作为结构是否被修改的判断依据。(在HashMap也有同样的modCount这个变量,它负责记录容器中数据的变化,如每次进行put,remove,replace都会去修改这个值,而ConcurrentHashMap使用modCount和HashMap略有不同,HashMap使用modCount是为了检测一些比较明显的并发问题,而ConcurrentHashMap的modCount则主要是使用在size方法中,而并发问题通过锁来解决,使用modCount来记录每次数据变更操作,但不会像HashMap那样抛出ConcurrentModificationException异常)。

2.连续做两遍segements循环统计segment出count,拿第一次的modCount和第二次的modCount做比较,如果相同意味着在第一遍统计size期间,segments并没有被改动,即统计出的count是正确的。

3.如果经判断发现两次统计出的modCount并不一致,那很尴尬,要重新启用最早所说的全部segment加锁的方式来进行count的获取和统计了,这样在次期间每个segement都被锁住,无法进行其他操作,统计出的count自然很准确。

之所以要先不加锁进行判断,道理很明显,就是不希望因为size操作获取这么多锁,因为获取锁不光占用资源,也会影响其他线程对ConcurrentHash的使用,影响并发情况下程序执行的效率。这个和ConcurrentHashMap创建的原因是违背的。

java map size 不准确_java1.7以前ConcurrentHashMap的size方法相关推荐

  1. java map 线程安全_Map线程安全的四种实现方法

    Map 线程安全四种方法: 1.使用 synchronized 关键字,代码如下 synchronized(anObject) { value=map.get(key); } 2.使用 JDK1.5提 ...

  2. java map 缓存数据_java使用hashMap缓存保存数据的方法

    本文实例讲述了java使用hashMap缓存保存数据的方法.分享给大家供大家参考,具体如下: private static final HashMap sCache = new HashMap(); ...

  3. Java Map中那些巧妙的设计

    简介: 他山之石可以攻玉,这些巧妙的设计思想非常有借鉴价值,可谓是最佳实践.然而,大多数有关Java Map原理的科普类文章都是专注于"点",并没有连成"线", ...

  4. ​Java Map中那些巧妙的设计

    最近拜读了一些Java Map的相关源码,不得不惊叹于JDK开发者们的鬼斧神工.他山之石可以攻玉,这些巧妙的设计思想非常有借鉴价值,可谓是最佳实践.然而,大多数有关Java Map原理的科普类文章都是 ...

  5. Java—Map集合详解(HashMap/Hashtable/LinkedHashMap/Properties/TreeMap/WeakHashMap/IdentityHashMap/EnumMap)

    关注微信公众号:CodingTechWork,一起学习进步. Map Map集合介绍   Map(也称为字典.关联数组)是用于保存具有映射关系的数据,保存两组值,key和value,这两组值可以是任何 ...

  6. Java map 知识

    Java map: Map 接口中键和值一一映射. 可以通过键来获取值 map 的方法如下: 序号 方法描述 1 void clear( )  从此映射中移除所有映射关系(可选操作). 2 boole ...

  7. java map常用类及其方法_Day50.Map类常用的方法 -Java常用类、集合#、IO

    Day50.Map类常用的方法 -Java常用类.集合#.IO Day50.Map类常用的方法 -Java常用类.集合#.IO Map类常用的方法 . 总结: 常用方法 添加: put(Object ...

  8. php 解析java map,java_java遍历Map的几种方法分析,本文实例分析了java遍历Map的几 - phpStudy...

    java遍历Map的几种方法分析 本文实例分析了java遍历Map的几种方法.分享给大家供大家参考,具体如下: Java代码: Map map=new HashMap(); map.put(" ...

  9. Java Map接口详解

    Map接口 Map接口概述 Map与Collection并列存在.用于保存具有映射关系的数据:key-value Map 中的 key 和 value 都可以是任何引用类型的数据 Map 中的 key ...

  10. java map遍历_Java中Map集合的两种遍历方式

    Java中的map遍历有多种方法,从最早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下Java中Map集合的两种遍历方式! 关于遍历Map集合的几 ...

最新文章

  1. 计图(Jittor) 1.1版本:新增骨干网络、JIT功能升级、支持多卡训练
  2. psfaddtable - 添加一个Unicode字符表到控制台字体中
  3. PHP执行批量mysql语句
  4. PyCharm无法启动的问题
  5. Codeforces Gym101257F:Islands II(求割点+思维)
  6. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
  7. 用python公众号开书城步骤_资源 | 开放Python书籍:一本短小精悍的初学者入门指南...
  8. 5分钟完成业务实时监控系统搭建,是一种什么样的体验?
  9. ArcGIS案例学习笔记-找出最近距离的垂线
  10. 【限时免费】LiveVideoStack Meet | 北京:卷时代,多媒体人 生存指北
  11. SAP UI5日期字段关于时区GMT的处理
  12. 卡特兰数 HDU2067 HDU4165 HDU1134
  13. [Sharepoint2007对象模型]第三回:Web应用程序(SPWebApplication)
  14. VUE自学日志03-模板语法
  15. pdf怎么压缩文件到最小?pdf文件怎么变小内存?
  16. 小白学python#Day5#笔耕不辍#每日一句,提高认知
  17. 码云上开源JAVA项目收藏
  18. 关于Flash的几点思考(Thoughts on Flash)
  19. Mac环境安装imagemagick及使用imagemagick拼接图片
  20. 乐优商城(四)商品规格管理

热门文章

  1. 《游戏设计师修炼之道:数据驱动的游戏设计》一1.4 来自政府和产业的挑战...
  2. 利用Karma、Jasmine 做前端单元测试
  3. makefile的编写(4)
  4. PTN OAM交互接口设计
  5. struts2与json的整合
  6. Tinker的简单接入
  7. Android常用提示框(dialog和popuwindow)
  8. 搜索引擎-Lucene
  9. 架构运维篇(五):Centos7/Linux中安装RocketMQ
  10. 通俗的语言解释一下什么是 RPC 框架