0

Integer ArrayList を反復処理して各要素の値を取得しようとしていますが、int value = ... でエラーが発生しています。

何が起こっているのかわからない。お知らせ下さい。

Iterator<Integer> listItr = executeList.iterator(); // iterator for the execute list 
    while (listItr.hasNext()) { // iterate through list and do work!
        int robIndex = listItr.next();
        int timer = fakeRob.exeCountDown(robIndex); // decrement first then return timer
        if (timer == 0) {// check if instr finished execution
            System.out.println("timer expired. fire");
            executeList.remove(executeList.indexOf(robIndex)); // 1. remove instr from exeList
            transitState(robIndex, EX, WB); // 2. transit from EX state to WB state
            int tag = fakeRob.getTag(robIndex); // get producer tag
            regFile.setRdy(tag); // 3a. set register file ready flag for this tag
            fakeRob.wakeUp(tag); // 3b. wake up instructions with this tag
        }
    }

エラー:

java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at sim.execute(sim.java:180)
at sim.<init>(sim.java:71)
at sim.main(sim.java:270

ありがとう、

ハンク

4

2 に答える 2

1

ローカル変数の値が「何かをする」ものであり、リストを変更していない場合、そこにいる間に外部スレッドがリストを変更しています。

それ以外の場合は、@edalorozo が提供するリンクを参照してください。

編集が追加されました

iterator.remove()イテレータのイディオムに慣れていないので、イディオムを使用することはありません。そして、それを短命で実装が不十分な Enumerator のものと常に混同していました。強化された for ループの前は、通常、非常に昔ながらfor (int i-0; i<foo.length; i++)のスタイルを使用してループしていました。また、すべてのイテレータが remove() をサポートしているわけではありません。

したがって、強化された for ループを使用するようになったときでも、「すべてを収集して後で削除する」スタイルに「慣れ」ました。コードでは、次のようになります。

ArrayList <Integer> toBeRemoved = new ArrayList <Integer>();
for (Integer robIndex : executeList) {
   // note, I distrust auto-unboxing, (see all the Java Puzzlers books!)
   // so I'd probably add an explicit unbox here
   int robIndexi = robIndex.intValue();

   int timer = fakeRob.exeCountDown(robIndexi); // decrement first then return timer
   if (timer == 0) {// check if instr finished execution
      toBeRemoved.add(robIndex);
      // all that other stuff here...
   }
}

// remove everything now
executeList.removeAll(toBeRemoved);
于 2012-05-05T23:37:05.657 に答える
1

おそらく、ループ内に何をしているのかを入れると、役立つでしょう。リストから要素を削除しようとしている場合は、 listItr.remove() を呼び出す必要があります。一般に、リストを変更する関数 (つまり、add()、set() など) をループ内で呼び出すべきではありません。

次のコードはこれをトリガーします

Iterator<Integer> it = executeList.iterator();
while (it.hasNext()) {
  Integer i = it.next();
  executeList.remove(i);
}

それを行う適切な方法は次のとおりです。

Iterator<Integer> it = executeList.iterator();
while (it.hasNext()) {
  Integer i = it.next();
  it.remove();
}

また、他のスレッド (上記のように) が問題になる可能性があります。イテレータは、Java が提供するすべてのコレクションのリスト自体によってサポートされていることに注意してください。したがって、反復中に別のスレッドがリストを変更すると、これに遭遇します。

于 2012-05-05T23:53:48.223 に答える