原逻辑:

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方法,这样锁的粒度更小,性能更好。
