我正在详分割析LongAdder算法。 LongAdder扩展了 Striped64 类,在该类中,基本方法是retryUpdate。以下代码摘自该方法;在链接的源代码中,它占据了212-222行:

try {  // Recheck under lock
  Cell[] rs; int m, j;
  if ( (rs = cells) != null &&
       (m = rs.length) > 0  &&
       rs[j = (m - 1) & h] == null) {
     rs[j] = r;
     created = true;
   }
} finally {
  busy = 0;
}

问题:这个try块怎么会失败?

注意数组访问
rs[j = (m - 1) & h]

不应抛出IndexOutOfBoundsException,因为按位与运算的结果始终小于或等于其整数参数的最小值,因此0

最佳答案

这非常像jdk代码本身中其他任何地方与ReentrantLock一起使用的模式。这里的“模式”是即使发生异常,也应始终释放锁定,因此通常将代码编写为:

Lock someLock...

try {
    // use someLock
} finally {
    someLock.unlock();
}

由于cellsBusy(从busy重命名)实际上是一个忙锁锁,因此这里的模式是相同的。因此:
cellsBusy = 0;

实际上是“释放锁”。因此,这实际上与失败无关,而与显式释放锁有关。我发现这很容易阅读,并能很好地理解代码。

关于java - LongAdder : How can the try block fail?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53195759/

10-10 11:49