ConcurrentHashMap核心原理,彻底给整明白了( 四 )
这是一个有参数的构造方法 。 如果你对未来存储的数据量有预估 , 我们可以指定哈希表的大小 , 避免频繁的扩容操作 。 tableSizeFor 这个方法确保了哈希表的大小永远都是 2 的 n 次方 。
注意这里传入的参数不是 initialCapacity , 而是 initialCapacity 的 1.5 倍 + 1 。 这样做是为了保证在默认 75% 的负载因子下 , 能够足够容纳 initialCapacity 数量的元素 。
ConcurrentHashMap (int initialCapacity) 构造函数总结下:
1、构造函数中并不会初始化哈希表;
2、构造函数中仅设置哈希表大小的变量 sizeCtl;
3、initialCapacity 并不是哈希表大小;
4、哈希表大小为 initialCapacity*1.5+1 后 , 向上取最小的 2 的 n 次方 。 如果超过最大容量一半 , 那么就是最大容量 。
tableSizeFor 是如何实现向上取得最接近入参 2 的 n 次方的 。 下面我们来看 tableSizeFor 源代码:
private static final int tableSizeFor(int c) {int n = c - 1;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;}复制代码依旧是二进制按位操作 , 这样一顿操作后 , 得到的数值就是大于 c 的最小 2 的 n 次 。 我们推演下过程 , 假设 c 是 9:
1、int n = 9 - 1n=82、n |= n >>> 1n=1000n >>> 1=0100两个值按位或后n=11003、n |= n >>> 2n=1100n >>> 2=0011n=1111复制代码到这里可以看出规律来了 。 如果 c 足够大 , 使得 n 很大 , 那么运算到 n |= n >>> 16 时 , n 的 32 位都为 1 。
总结一下这一段逻辑 , 其实就是把 n 有数值的 bit 位全部置为 1 。 这样就得到了一个肯定大于等于 n 的值 。 我们再看最后一行代码 , 最终返回的是 n+1 , 那么一个所有位都是 1 的二进制数字 , +1 后得到的就是一个 2 的 n 次方数值 。
- 王兴称美团优选目前重点是建设核心能力;苏宁旗下云网万店融资60亿元;阿里小米拟增资居然之家|8点1氪 | 美团
- 体验|vivo的OriginOS怎么样?体验报告来袭:虽惊艳但核心问题未解决
- 山东国晶|山东企业攻克OLED面板蒸镀源核心技术瓶颈
- 媒介|智媒介:软文发布文案的核心写作技巧介绍
- 并发容器ConcurrentHashMap
- 随机森林(Random Forest)算法原理
- C/C++协程学习笔记丨C/C++实现协程及原理分析视频
- C++核心准则?:标准库array或vector好于C数组
- 「书讯」移动互联网对企业核心能力影响研究
- 领导者的核心是战略定力
