1 ConcurrentHashMap的底层原理
- HashTable读写时都给整个集合加锁;ConcurrentHashMap使用可重入锁的分段锁技术。
- ConcurrentHashMap集合的segments数组中有2的N次方个Segment对象。
- 两次hash运算:首先定位到Segment,之后定位到Segment内的具体数组下标。
ConcurrentHashMap并发读写:
- 不同Segment的读写可以并发执行;
- 同一Segment的写和读可以并发执行;
- 同一Segment的并发写入会被阻塞。
2 调用size()方法时解决一致性问题
为了尽量不锁住所有Segment,首先乐观地假设size()过程中不会有修改。当尝试到一定次数,才无奈转为悲观锁,锁住所有Segment保证强一致性。
- 遍历所有Segment;
- 把Segment的元素数量累加起来;
- 把Segment的修改次数累加起来;
- 判断所有Segment的总修改次数是否大于上一次的总修改次数。如果大于,说明统计过程中有修改,重新统计,尝试次数+1;如果等于,说明没有修改,统计结束;
- 如果尝试次数超过阈值,则对每个Segment加锁,重新统计;
- 再次判断所有Segment的总修改次数是否大于上一次的总修改次数。由于已经加锁,次数一定和上次相等。
- 释放锁,统计结束。