LongAdder:try 块怎么会失败?

use*_*513 5 java algorithm finally try-catch

我正在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;
}
Run Code Online (Sandbox Code Playgroud)

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

注意数组访问

rs[j = (m - 1) & h] 
Run Code Online (Sandbox Code Playgroud)

不应该抛出 anIndexOutOfBoundsException因为按位与运算的结果总是小于或等于其整数参数的最小值,因此 0 <= j <= m-1 在数组的边界内。

Eug*_*ene 2

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

Lock someLock...

try {
    // use someLock
} finally {
    someLock.unlock();
}
Run Code Online (Sandbox Code Playgroud)

由于cellsBusy(它被重命名为busy)实际上是一个忙自旋,所以这里的模式有点相同。像这样:

cellsBusy = 0;
Run Code Online (Sandbox Code Playgroud)

实际上就是“释放锁”。所以这并不是真正的失败,因为它是关于显式释放锁。我发现这更容易阅读和推理代码。