优化CtSph#lookProcessChain 创建拦截链方法(减少第一次创建拦截链持有锁占用时间,提升rt,减少gc压力)
- Dominant language
- Java
- Stars
- 23.1k
- Forks
- 8.1k
- PR merge metrics
- No merged PRs in 30d
Description
### 原逻辑:

chainMap 是一个 volatile 修饰的 Map。首次获取 ProcessorSlotChain 时,如果为空,旧逻辑会进入同步块,new 一个新的 map,并通过 putAll 拷贝原有数据后再新增,最终整体替换 chainMap,利用 volatile 替换引用实现可见性。
### 优化后:

新逻辑为在同步块中直接put。(synchronized本身保证可见性)
### 好处:
1: **提高rt:**
避免在高并发下频繁进行 putAll 拷贝,特别是在 map 较大(如含有数百个资源)的情况下,putAll花费的时间越多,优化可以减少锁占用时间,从而提高rt。
2: **减少GC压力:**
直接put无需频繁创建大量短生命周期的临时 map,降低内存占用和 GC 负担。
**理由:**
看了整个代码后,发现真正使用chainMap的地方也只有lookProcessChain这一个方法,其余的方法比如resetChainMap、getChainMap是**default**修饰的,仅仅用于测试调用,**只能在当前包调用**,所以这里我没有加synchronized。而entrySize方法是一个**public**修饰的方法,为了保证其可见性,我使用了synchronized关键字。
synchronized关键字本身通过内存屏障保证了可见性,因此chainMap不需要加**volatile**关键字修饰。
类似的实现比如java中的Collections.synchronizedMap()。

**后续思考:**

当资源数限制(如 6000)放开后,或者可以允许超一点点去追求极致的性能的话,代码还可以进行如下优化:
chainMap使用ConcurrentHashMap,不需要显示进行加锁,直接采用ConcurrentHashMap#computeIfAbsent方法,这样锁的粒度更小,性能更好。

Contributor guide
Assessment
This issue has not been assessed yet.