并发修改异常ConcurrentModificationException
Posted ynhwl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发修改异常ConcurrentModificationException相关的知识,希望对你有一定的参考价值。
今天遇到这样的需求:
------》
一个监控页面定时刷新,当前刷新出来的数据中具有一列是ip:port的组合,当前显示的数据,每一次刷新都是不规律显示的,要求按一定秩序排列显示。
问题分析:
因为前端框架不易修改排序的原因,选择了在后台排序,没有sql查询,排除了order by,于是乎想到了对查询结果集来一次“基因重组”的操作。
当前的方式:数据对象存在一个List集合中,将该List转成json返回页面,鉴于此,想到了在List集合上做操作;
计划的方法:遍历集合,在遍历中提取对象的IP+端口属性——>字符串并接——>转为long型来比较大小——根据该属性的大小排序对象,装回去集合中,然后同原来的转为json返回页面。
遇到的问题:
集合的遍历排序,操作起来不是那么方便,没有第i位,第i+2位这样的方便;
所以转变了排序方法,先提取出所有的 ip+port,转为long型,装入新定义的数组A,正常排序。
遍历集合,与排好的A集合对号入座,实现对象集合的排序。
提取ip+port,并排序:
List<Long> ipPortList = new ArrayList<Long>(); for( RedisClusterInfoPage redisClusterInfo : resultList){ String ipAndPortTmp = RedisClusterInfoController.MyIpAndPortFilter( redisClusterInfo.getAddr() ); Long LongTypeipAndPortTmp = Long.parseLong( ipAndPortTmp ); ipPortList.add( LongTypeipAndPortTmp ); } Collections.sort( ipPortList );
让原乱序对象集合对号入座:
for ( Long ipPort : ipPortList){ for ( RedisClusterInfoPage redisClusterInfo : resultList2 ){ String ipAndPort2 = RedisClusterInfoController.MyIpAndPortFilter( redisClusterInfo.getAddr() ); Long LongipAndPort2 = Long.parseLong( ipAndPort2 ); if( LongipAndPort2.longValue() == ipPort.longValue() ){ resultList3.add( redisClusterInfo ); } }
}
对号入座的时候遇到的问题:
ConcurrentModificationException,at:
resultList3.add( redisClusterInfo );
嗯,原来是在我add的时候,有其他线程在读这个集合
为了解决问题,那就只能操作这个集合的副本,于是乎添加了一个集合,作为原集合的副本来操作,最终是实现了。
效果如下:
以上是关于并发修改异常ConcurrentModificationException的主要内容,如果未能解决你的问题,请参考以下文章
ConcurrentModificationException(并发修改异常)的解决
ConcurrentModificationException并发修改异常