喝咖啡的睡眠族 2023-03-19 22:22 采纳率: 50%
浏览 36
已结题

Spring元码中的神奇操作

img

在spring源码中,有一段关于注册bean的处理:


            if (hasBeanCreationStarted()) {
                // Cannot modify startup-time collection elements anymore (for stable iteration)
                synchronized (this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {

                        // 没明白这一行的意义
                        Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;

                        // 为什么不直接使用remove()去删除元素呢?而且复制->删除->替换?
                            // this.manualSingletonNames.remove(beanName);
                    }
                }
            }

为什么不直接使用remove()去删除元素呢?而且复制->删除->替换?
求解

  • 写回答

2条回答 默认 最新

  • 瞬间的未来式 2023-03-19 22:52
    关注

    这段代码中的注释已经解释了这一行代码的作用:为了稳定迭代,不能再修改启动时的集合元素了。换句话说,如果我们在遍历这个集合时删除了一个元素,就会抛出ConcurrentModificationException异常,因为集合在遍历时已经被修改了。

    因此,这里使用了复制、删除、替换的方式来修改manualSingletonNames集合中的元素。先复制原来的集合,然后从副本中删除要删除的元素,最后用副本替换原来的集合,从而保证了在迭代集合的同时修改集合元素的安全性。

    这种复制、删除、替换的方式可以确保在迭代集合时不会抛出ConcurrentModificationException异常,但也会增加一定的性能开销。所以,如果集合元素的修改是在迭代之前进行的,可以直接使用remove()方法删除元素,不需要复制、删除、替换的操作。但如果在迭代期间进行了集合元素的修改,就需要采用复制、删除、替换的方式来确保安全性。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 3月27日
  • 已采纳回答 3月19日
  • 创建了问题 3月19日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改