ConcurrentHashMap是怎么记录元素个数size的?
1 个回答
首先你要快乐,其次都是其次。古薰儿在 `ConcurrentHashMap` 中,记录元素个数 `size` 的方式比 `HashMap` 要复杂得多,因为 `ConcurrentHashMap` 需要保证在高并发环境下的线程安全。 ### 1. `ConcurrentHashMap` 的 `size` 记录机制 `ConcurrentHashMap` 不能像 `HashMap` 一样简单地使用一个 `int` 类型的变量来记录 `size`,因为在并发环境下,这样的做法会导致竞争条件,破坏线程安全。相反,`ConcurrentHashMap` 采用了一种基于分段计数的方法,即通过 `baseCount` 和 `CounterCell` 数组来记录元素个数。 #### 1.1 `baseCount` 和 `CounterCell` 数组 - **`baseCount`**:这是一个 `volatile` 修饰的 `long` 类型变量,初始情况下,它记录了 `ConcurrentHashMap` 的元素个数。当并发较低时,`size` 增加或减少时,直接通过 CAS 操作更新这个变量。 - **`CounterCell`**:当并发度增加,CAS 操作失败时,`ConcurrentHashMap` 会使用一个 `CounterCell` 数组来记录元素个数的增量。每个 `CounterCell` 实例也是 `long` 类型,用于在高并发情况下分散写入压力,避免多个线程争用同一个变量。 #### 1.2 `sumCount()` 方法 `sumCount()` 方法用于计算 `ConcurrentHashMap` 的当前 `size`。它会返回 `baseCount` 的值加上 `CounterCell` 数组中每个元素的值总和。 ```java final long sumCount() { CounterCell[] as = counterCells; CounterCell a; long sum = baseCount; if (as != null) { for (int i = 0; i < as.length; ++i) { if ((a = as[i]) != null) sum += a.value; } } return sum; } ``` #### 1.3 `addCount()` 方法 `addCount()` 方法在添加或删除元素时调用,用于更新 `size`。它首先尝试直接更新 `baseCount`,如果失败,则尝试将增量存储在 `CounterCell` 中。如果 `CounterCell` 不存在或需要扩展,则会动态创建和调整 `CounterCell` 数组。发布于 2024-08-20 07:48 •IP属地 青海举报评论收藏
公众号进入网站体验更佳

