簡體   English   中英

遍歷列表但未修改列表時發生ConcurrentModificationException

[英]ConcurrentModificationException while iterating through a list but not modifying it

我正在使用JMeter運行我的應用程序以進行負載測試,並在(我認為)它不應該出現的情況下獲得ConcurrentModificationException 這種情況僅發生在少數情況下,並非全部發生。

我有一個ArrayList ,它是一個類變量,通過方法在其中添加元素。 稍后,在准備列表之后調用另一種方法,使用stream繼續進行迭代,並使用一些過濾器准備本地數組列表,如下所示

...
//class variable getting elements from a separate method
List<String> myGlobalList = new ArrayList(); 
...

public String returnValue(String _value){
  List myLocalList = new ArrayList();
  myGlobalList.stream().filter(ele -> {
    ele = ele.replaceAll("\\[(.*?)\\]", "$1");

    String[] strArr = ele.split(",");
    for(String sArr : strArr) {
      if(sArr.contains(_value)){
        System.out.println("sArr ---- > "+sArr);
        myLocalList.add(sArr);
        return true ;
      }
    }
    return false;
  }).findFirst();

  return myLocalList.size()>0 ? myLocalList.get(0): null;
}

findFirst()方法僅在負載下拋出ConcurrentModificationException (並非針對每個請求)。

無法弄清楚為什么會這樣。 我缺少任何鑰匙嗎? 在所有情況下如何修改此代碼以避免此異常?

更新:

下面是來自堆棧跟蹤的摘錄

java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1353)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
at com.pkg.MyClass.returnValue(MyClass.java:501)

您是否不需要獲取列表中的第一個字符串? 為什么不使用List就不獲取它:

  public String returnValue(String _value){   
  String findFirst = myGlobalList.stream().filter(ele -> {
    ele = ele.replaceAll("\\[(.*?)\\]", "$1");

    String[] strArr = ele.split(",");
    for(String sArr : strArr) {
      if(sArr.contains(_value)){
        System.out.println("sArr ---- > "+sArr);
        //myLocalList.add(sArr);
        return true ;
      }
    }
    return false;
  }).findFirst().get();

  return findFirst;
}

編輯

帶有可選檢查:

        Optional<String> findFirst = myGlobalList.stream().filter(ele -> {
        ele = ele.replaceAll("\\[(.*?)\\]", "$1");

        String[] strArr = ele.split(",");
        for (String sArr : strArr) {
            if (sArr.contains(_value)) {
                System.out.println("sArr ---- > " + sArr);
                // myLocalList.add(sArr);
                return true;
            }
        }
        return false;
    }).findFirst();
    return findFirst.isPresent() ? findFirst.get() : null;

編輯2

findFirst異常,因為原始列表已更改,請嘗試使用collect將結果收集到新列表中,然后獲取第一個值:

 return myGlobalList.stream().filter(ele -> {
        ele = ele.replaceAll("\\[(.*?)\\]", "$1");

        String[] strArr = ele.split(",");
        for (String sArr : strArr) {
            if (sArr.contains(_value)) {
                //System.out.println("sArr ---- > " + sArr);
                // myLocalList.add(sArr);
                return true;
            }
        }
        return false;
    }).collect(Collectors.toList()).get(0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM