You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sentinel源码中map.put直接添加与创建新HashMap替换旧Map的区别

问题

我在阅读Sentinel的源码时发现,当需要向Map中添加条目时,并未直接使用map.put方法,而是创建一个新的HashMap来替换旧Map,示例代码如下:

public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {

    private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);

    @Override
    public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
        throws Throwable {
      
        DefaultNode node = map.get(context.getName());
        if (node == null) {
            synchronized (this) {
                node = map.get(context.getName());
                if (node == null) {
                    node = new DefaultNode(resourceWrapper, null);
                    // create a new hashmap
                    HashMap<String, DefaultNode> cacheMap = new HashMap<String, DefaultNode>(map.size());
                    cacheMap.putAll(map);
                    cacheMap.put(context.getName(), node);
                    map = cacheMap;
                    ((DefaultNode) context.getLastNode()).addChild(node);
                }

            }
        }

        context.setCurNode(node);
        fireEntry(context, resourceWrapper, node, count, prioritized, args);
    }
...
}

请问这两种实现方式之间有什么区别?


回答

这两种写法的核心差异体现在并发场景下的性能、线程安全保障逻辑上,具体区别如下:

  • 线程安全的实现逻辑不同
    如果直接用map.put,普通HashMap本身非线程安全,必须给整个put操作加锁,这会导致所有读写操作都阻塞在锁上;而Sentinel的写法采用拷贝替换+volatile:读操作完全无锁(map被volatile修饰,保证多线程下的可见性),只有新增节点时才加锁做拷贝替换,锁仅在写操作时生效,读操作全程不受影响。

  • 读写性能差异明显
    高并发场景下,直接加锁的put会让所有读请求等待锁释放,性能瓶颈突出;而拷贝替换的方式,读操作无锁并行,只有写操作短暂持有锁,整体读写吞吐量更高。

  • 数据一致性保障不同
    直接put在锁保护下能保证单个操作原子性,但多线程操作时,读请求可能看到Map的中间更新状态;而拷贝替换的方式中,map引用的切换是原子性的(volatile特性),读请求要么看到旧的完整Map,要么看到新的完整Map,不会出现半更新的不一致状态。

  • 内存开销有区别
    拷贝替换每次新增都要创建新HashMap并复制旧数据,会带来额外内存开销和短暂GC压力;直接put没有这部分开销,内存利用更高效。

内容的提问来源于stack exchange,提问作者moreHope

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:01:07