1. 程式人生 > >並發修改異常ConcurrentModificationException

並發修改異常ConcurrentModificationException

端口 json color bubuko 要求 cti 好的 比較 字符串

今天遇到這樣的需求:

  技術分享圖片------》技術分享圖片

一個監控頁面定時刷新,當前刷新出來的數據中具有一列是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