BUG探究 ConCurrentHashMap 源码中的 bug

一、背景

之前写过一篇《ConCurrentHashMap 源码解析》。

一读者,加了我微信,前几天发信息说:

解析不太对吧,源码好像有问题!

addCount 方法中的错误如下:
在这里插入图片描述
起初我内心,是相当抗拒的,

JDK8 源码能写错?闹着玩么?

常用并发工具类啊,怎么可能有错!

硬着头皮,看了大半天,

好像是不对哦!问问度娘,查查官网,

我去!!!JDK8 的源码,确实写的不对!!!

二、结论

我查到了 Oracle 官网上,此 bug 的说明——“ConcurrentHashMap.addCount()
在这里插入图片描述
为什么错了? 为什么?


  if (sc < 0) {
   
      if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
          sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
          transferIndex <= 0)
          break;
      if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
          transfer(tab, nt);
  }

对于 sc == rs + 1 来说,等号左边是 负数,

而等号右边是 正数,这个判断永远是 false ;

稍微改下就对了: (sc >>> RESIZE_STAMP_SHIFT) == rs + 1

好了,对于面试来讲,你能扯出一个 JDK 的 bug,

很拽!很牛气!这就行了。

下面的源码解析,很枯燥,也很烧脑。

压根没看过源码的,还是别往下看了。
`

-------------- !!!劝退分割线!!!--------------
`

三、bug 的影响分析

这个 bug 对 ConCurrentHashMap 有啥大的影响么?

大的影响,没有!小的影响,也可以认为没有。

你想啊,这是 JDK8 常用并发工具类,真有问题,早就修复了。

这个问题,到 JDK12 才更正了,也能侧面看出来,它无足轻重!

如果非要说有啥影响,在极端高并发时,某些线程会多执行几行代码,

0.001 毫秒为一个单位,耗时会多几个单位吧。

为什么,这个后面说道源码再细说。

网上其实也有文章,说这个 bug 的,

像我这样,解释详细的文章,就几乎没有了。

(sc >>> RESIZE_STAMP_SHIFT) == rs + 1

这个为什么是对的,可能这是全网独一份的解释。

自夸了,哈哈!!

四、sc == rs + 1 判断无效,源码解析

addCount 源码解析》,你先看下,这篇文章,

对相关源码有个详细的了解。

   Node<K,V>[] tab, nt; int n, sc;
   while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
          (n = tab.length) < MAXIMUM_CAPACITY) {
   
       int rs = resizeStamp(n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值