xmemcached 1.2.6.2紧急发布

今年在阅读某个项目源码的时候看到DelayQueue的使用, xmemcached  1.2.6.1的重连任务也是采用DelayQueue管理,ReconnectRequest实现Delayed接口,我突然想起去review下xmc的源码,发现一个严重的BUG,原始代码如下:
public  final  class ReconnectRequest  implements Delayed {
       public  long getDelay(TimeUnit unit) {
         return  nextReconnectTimestamp - System.currentTimeMillis();
    }
}

    getDelay返回该任务还剩下多少时间可以被执行,将下次执行的时间戳减去当前时间即可,问题在于这里返回的是毫秒,而没有调用getDelay传入的TimeUnit做转换,在DelayQueue内部其实是用纳秒做单位交给Condition对象去等待
   for (;;) {
                E first = q.peek();
                 if (first ==  null) {
                    available.await();
                }  else {
                     long delay =  first.getDelay(TimeUnit.NANOSECONDS);
                     if (delay > 0) {
                         long tl = available.awaitNanos(delay);
                    }  else {
                        E x = q.poll();
                         assert x !=  null;
                         if (q.size() != 0)
                            available.signalAll();  //  wake up other takers
                         return x;

                    }
                }
            }
   
     最终导致的问题是, awaitNanos很快返回( awaitNanos接受的是纳秒,这里却传入毫秒) ,循环执行发现重新计算的delay仍然大于0,循环等到getDelay返回的越来越小直到0才执行相应的Task,,造成的现象是在重连的时候cpu占用率很高。

     单元测试的时候没有发现这个问题,主要是因为功能正常,没有关注资源消耗情况,因此惭愧地忽略了。

      解决的办法很简单,修改getDelay方法即可:
     public  long getDelay(TimeUnit unit) {
         return unit.convert(
                nextReconnectTimestamp - System.currentTimeMillis(),
                TimeUnit.MILLISECONDS);
    }

      这个BUG比较严重,已经升级1.2.6.1的朋友建议马上升级到1.2.6.2,使用maven的朋友只要修改版本即可,没有使用maven的请到这里下载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值