Hashmap为什么容量是2的幂次,附加一个轮训算法。

我们知道hashmap底层是一个数组+连表的数据结构。

transient Node<K,V>[] table;

数组的长度为什么选择2的幂次。 比如 8或者16,为什么不能为7或者15呢?

答:为了效率, (n - 1) & hash   其中N为16, hash为对象的哈希值,那么会返回【0-15】,正好作为数组的下标,我们知道&效率是最快的。

我们来看一下16的二进制为【0001 0000】 ,15的二进制位【0000 1111】。

【0000 1111】 & hash, &=》俩边为1的为1否则为0,那么不管hash的值是多少,最后的结果肯定<=15,这样就很高效。

那么如果长度是15呢, (n-1)=14 二进制为【0000 1110】。那么只能返回【0,2,4,6,8,14】,显然就不对了。

 

如果一个数组的长度正好是2的幂次,可以写出一个很高效的轮训算法,并且支持并发访问。

final AtomicInteger idx = new AtomicInteger();
    for (int i = 0; i < 1000; i++) {
    System.out.println(idx.getAndIncrement() & 16 - 1);
}

如果不是2的幂次,那么可以这么写,同样支持并发访问。

private final AtomicInteger nextServerCyclicCounter = new AtomicInteger(0);

private int incrementAndGetModulo(int modulo) {
        for (;;) {
            int current = nextServerCyclicCounter.get();
            //拿出当前nextServerCyclicCounter的值+1 对 modulo 取模
            //计算出的值next肯定小于modulo
            int next = (current + 1) % modulo;
            //乐观锁设值 如果nextServerCyclicCounter当前值还等于current,则设值成功,否则死循环解决并发问
            if (nextServerCyclicCounter.compareAndSet(current, next))
                return next;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值