posts - 35, comments - 0, trackbacks - 0, articles - 0
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          ConcurrentModificationException

          Posted on 2012-07-17 17:01 timelyxyz 閱讀(110) 評(píng)論(0)  編輯  收藏

          突然拋了一個(gè)concurrentModificationException錯(cuò)誤,Iterator的一個(gè)基本概念沒(méi)有掌握導(dǎo)致的這個(gè)錯(cuò)誤,就是在Iterator的實(shí)現(xiàn)類。比如Hashtable里面的內(nèi)部類
           private class Enumerator<T> implements Enumeration<T>, Iterator<T>

          會(huì)在next,或者remove的時(shí)候檢查當(dāng)前集合是否會(huì)在修改狀態(tài),如果是的話,就會(huì)拋出 ConcurrentModificationException,而他自己remove則是使用了同步的方法,而且同步了modCount;expectedModCount;

           1 public T next() {
           2      if (modCount != expectedModCount)
           3          throw new ConcurrentModificationException();
           4      return nextElement();
           5  }
           6 
           7 
           8 public void remove() {
           9      if (!iterator)
          10         throw new UnsupportedOperationException();
          11      if (lastReturned == null)
          12         throw new IllegalStateException("Hashtable Enumerator");
          13      if (modCount != expectedModCount)
          14         throw new ConcurrentModificationException();
          15 
          16      synchronized(Hashtable.this) {
          17         Entry[] tab = Hashtable.this.table;
          18         int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
          19 
          20      for (Entry<K,V> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
          22       if (e == lastReturned) {
          23          modCount++;
          24          expectedModCount++;
          25          if (prev == null)
          26             tab[index] = e.next;
          27          else
          28             prev.next = e.next;
          29          count--;
          30          lastReturned = null;
          31          return;
          32       }
          33      }
          34      throw new ConcurrentModificationException();
          35      }
          36     }
          37     }
          而自己在next的同時(shí),修改了這個(gè)集合,導(dǎo)致了這個(gè)錯(cuò)誤的出現(xiàn)

           

          在Map或者Collection的時(shí)候,不要用它們的API直接修改集合的內(nèi)容,如果要修改可以用Iterator的remove()方法,例如:
          1 public void setReparation( Reparation reparation ) {
          2         for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparations為Collection
          3             Reparation repa = (Reparation)it.next();
          4             if (repa.getId() == reparation.getId()){
          5                 this.reparations.remove(repa);
          6                 this.reparations.add(reparation);
          7             }
          8         }
          9    }

           

          如上寫(xiě)會(huì)在運(yùn)行期報(bào)ConcurrentModificationException,可以如下修改:

           

           1  public void setReparation( Reparation reparation ) {
           2         boolean flag = false;
           3         for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparations為Collection
           4             Reparation repa = (Reparation)it.next();
           5             if (repa.getId() == reparation.getId()){
           6                 it.remove();
           7                 flag = true;
           8                 break;
           9             }
          10         }
          11         if(flag){
          12           this.reparations.add(reparation);
          13         }
          14     }

           

           

          原文摘自 alreal 

           


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 三明市| 桃源县| 芒康县| 郁南县| 阳谷县| 汽车| 南乐县| 柳林县| 思茅市| 油尖旺区| 阿巴嘎旗| 特克斯县| 南汇区| 宜兴市| 溧阳市| 平陆县| 禹城市| 嘉荫县| 南漳县| 砀山县| 耒阳市| 弋阳县| 金华市| 特克斯县| 宁陕县| 武隆县| 蚌埠市| 盈江县| 雷波县| 丽水市| 高尔夫| 嘉黎县| 鄂伦春自治旗| 汕尾市| 涞水县| 内黄县| 高邑县| 琼海市| 昌江| 邯郸县| 五大连池市|