多线程增加 LongAdder 的值的状态变化分析

假设我们有一个 LongAdder 实例,初始状态如下:

  • base: 0

  • Cell 数组: 未创建

接下来,我们将模拟多个线程对 LongAdder 的并发更新操作。以下是状态变化的过程:

1、初始状态:

  • base: 0

  • Cell 数组: 未创建

2、线程 A 开始操作:

  • 线程 A 尝试对 base 进行 CAS 更新,将 base 的值从 0 增加到 1。

  • 成功后,base 的值变为 1。

  • 当前状态:

base: 1

Cell 数组: 未创建

3、线程 B 开始操作:

线程 B 同样尝试对 base 进行 CAS 更新,但由于线程 A 已经更新了 base 的值,线程 B 的 CAS 更新失败。

  • 线程 B 继续尝试更新,如果连续失败达到阈值(默认为 64 次),则触发转换操作。

  • 此时,base 的值被复制到一个新的 Cell 数组的第一个元素中,并且 base 的值被清零。

  • 当前状态:

base: 0

Cell 数组: [1]

4、线程 B 完成操作:

  • 线程 B 对 Cell 数组的第一个元素进行 CAS 更新,将值从 1 增加到 2。

  • 当前状态:

base: 0

Cell 数组: [2]

5、线程 C 开始操作:

  • 线程 C 尝试对 Cell 数组的第一个元素进行 CAS 更新,将值从 2 增加到 3。

  • 如果线程 C 的 CAS 更新失败,说明有其他线程正在更新同一个 Cell 元素,这时 Cell 数组会扩展。

  • 假设线程 C 的 CAS 更新失败,Cell 数组扩展为 [2, 0]。

  • 线程 C 将值从 0 增加到 1,更新第二个 Cell 元素。

  • 当前状态:

base: 0

Cell 数组: [2, 1]

6、线程 D 开始操作:

  • 线程 D 尝试对 Cell 数组的第一个元素进行 CAS 更新,将值从 2 增加到 3。

  • 成功后,第一个 Cell 元素的值变为 3。

  • 当前状态:

base: 0

Cell 数组: [3, 1]

7、线程 E 开始操作:

  • 线程 E 尝试对 Cell 数组的第二个元素进行 CAS 更新,将值从 1 增加到 2。

  • 成功后,第二个 Cell 元素的值变为 2。

  • 当前状态:

base: 0

Cell 数组: [3, 2]

最终状态

经过上述操作后,LongAdder 的最终状态为:

  • base: 0

  • Cell 数组: [3, 2]

此时,LongAdder 的总和可以通过调用 sum() 方法计算得出,即 3 + 2 = 5。

通过这种方式,LongAdder 能够有效地处理多线程并发更新的情况,减少竞争并提高并发性能。