ConcurrentHashMap 的 size 方法原理分析
面试题
这是同一个面试的时候别人问的,我只是记得看过,在concurrenthashmap中会统计多次,当时就说会统计两次进行比较,人家接着问为啥。。。我傻了一下,这不是明摆着两次统计的中间有新的变化了,会导致统计不准确吗?当时也不知道说啥好,以为他有新的点,就说不知道。面试时很多问题其实冷静下来想一下,可以更进一步的,有时候其实也是怕他更进一步后下面的挖坑挖大了。
下面具体说一下这个size方法:
代码就不贴了。只说原理。
众所周知,concurrenthashmap有很多歌segments,首先遍历segments将每个segment的count加起来作为整个concurrenthashMap的size。如果没有并发的情况下这自然就可以了,但这是多线程的,如果前脚统计完后脚有变化了,这就不准确了,源码中引入了,modCount和两次比较来实现size的确认。具体过程是:
1.进行第一遍遍历segments数组,将每个segemnt的count加起来作为总数,期间把每个segment的modCount加起来sum作为结果是否被修改的判断依据。
这里需要提一下modCount,这个是当segment有任何操作都会进行一次增量操作,代表的是对Segment中元素的数量造成影响的操作的次数,这个值只增不减!!!!只增不减很重要,这样就不会出现一个segment+1,导致modcount+1,而另一个segment-1,即modcount-1 ,从而在统计所有的时候modcount没有变化。
2.size操作就是遍历了两次所有的Segments,每次记录Segment的modCount值,然后将两次的modCount进行比较,如果相同,则表示期间没有发生过写入操作,就将原先遍历的结果返回,如果不相同,则把这个过程再重复做一次,如果再不相同,则就需要将所有的Segment都锁住,然后一个一个遍历了。
3.如果经判断发现两次统计出的modCount并不一致,那就如上所说,要重新启用全部segment加锁的方式来进行count的获取和统计了,这样在此期间每个segement都