consul配置修改刷新触发的java.util.ConcurrentModificationException异常 您所在的位置:网站首页 util包下有哪些类 consul配置修改刷新触发的java.util.ConcurrentModificationException异常

consul配置修改刷新触发的java.util.ConcurrentModificationException异常

2023-06-07 03:33| 来源: 网络整理| 查看: 265

遇到的问题

项目中用到consul作为配置中心,在修改consul配置时,会发现服务报出集合类修改异常:

java.util.ConcurrentModificationException at java.util.ArrayList.forEach(ArrayList.java:1260) 问题分析

Java1.8

// ArrayList 部分源码 public void forEach(Consumer action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @SuppressWarnings("unchecked") final E[] elementData = (E[]) this.elementData; final int size = this.size; for (int i=0; modCount == expectedModCount && i // 此处抛出异常 (line: 1260) throw new ConcurrentModificationException(); } }

一开始并不能确定是consul配置刷新导致的。经过试验和跟踪,发现确实在修改consul配置时,正在使用集合类型的配置项导致的。

复现方法如下:

consul中的配置

# consul中配置 testKeys: - a - b - c - d - e public static void main(String[] args) { ConfProperties p = ctx.getBean(ConfProperties.class); List list = p.getTestKeys(); System.out.println(list.hashCode()); System.out.println(list.size()); list.forEach( k -> { System.out.println(k); try { Thread.sleep(20000L); } catch (InterruptedException e) { throw new RuntimeException(e); } }); System.out.println(list.hashCode()); System.out.println(list.size()); } @Configuration @Data public calss ConfProperties { private List testKeys; }

在运行过程中,去修改consul配置,会看到异常抛出。也就是ArrayList的modCount发生了改动;具体经过debug跟踪是spring cloud 组件实现的动态配置刷新中对集合类的配置更新使用了合并操作:

具体代码位于CollectionBinder.merge方法中

//org.springframework.boot.context.properties.bind.CollectionBinder#merge try { existingCollection.clear(); existingCollection.addAll(additional); return this.copyIfPossible(existingCollection); } catch (UnsupportedOperationException var5) { return this.createNewCollection(additional); }

addAll 修改了原集合,modCount也会随之修改。

解决方法

一种比较简单的解决办法是在每次获取集合类配置时,拷贝出一个新的集合,避免引用集合被修改;

@Configuration @Data public calss ConfProperties { private List testKeys; public List getTestKeys() { return testKeys != null ? new ArrayList(testKeys) : Collections.emptyList(); } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有