<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    在多線程的情況下是由Iterator遍歷修改集合對象,報ConcurrentModificationException()異常的根因分析。

             在多線程下使用Iterator來迭代對象時,總會包ConcurrentModificationException();異常,經過我對list和Iterator相關源碼的分析,終于搞明白了這個問題: 
             下面結合源代碼來討論這個問題:

              1、當我們調用一個List的iterator時,其實返回的并不是Itr對象(Iterator是一個接口),請看代碼:
    1  public Iterator<E> iterator() {
    2    return new
     Itr();
    3  }
           
           2、在Itr類中有這么一句話  int expectedModCount = modCount;首先講一下這兩個變量的含義:
                 expectedModCount :創建當前的Itr對象時集合對象被修改的次數。他是Itr的變量。
                 modCount:記錄集合對象從創建到當前時間被做修改的次數。(集合每進行一次增刪改查都會使modCount),他是Itr的外部類AbstractList
                 的變量,且該變量在 AbstractList中被如此修飾protected transient int modCount = 0; 
                另外,Itr自己對集合對象進行了修改后,他會維持expectedModCount 和modCount的保持相等,請看以下代碼
     1 //Itr的刪除方法
     2 public void remove() {
     3         if (lastRet == -1
    )
     4         throw new
     IllegalStateException();
     5 
                checkForComodification();
     6 

     7         try {
     8         AbstractList.this
    .remove(lastRet);
     9         if (lastRet <
     cursor)
    10             cursor--
    ;
    11         lastRet = -1
    ;
    12         expectedModCount =
     modCount;
    13         } catch
    (IndexOutOfBoundsException e) {
    14         throw new
     ConcurrentModificationException();
    15 
            }
    16     }

                在代碼的12行,Itr保證了expectedModCount 和modCount值的相等 ,modCount的值發生了改變嗎,他改變了,帶代碼的第8行改變的,請看此處的代碼:
             
     1public E remove(int index) {
     2
        RangeCheck(index);
     3

     4    modCount++
    ;
     5    E oldValue =
     elementData[index];
     6

     7    int numMoved = size - index - 1
    ;
     8    if (numMoved > 0
    )
     9        System.arraycopy(elementData, index+1
    , elementData, index,
    10
                     numMoved);
    11    elementData[--size] = null// Let gc do its work

    12
    13    return oldValue;
    14    }

               在代碼的第四行modCount發生了改變。 由此可以看出,在我們調用集合對象的iterator()方法的remove時總會使list的modCount的值自增1,但是Itr會自己維護該值和expectedModCount 的一致。
           3、試問:如果expectedModCount 和modCount的值如果不相等,會有什么問題呢,這就是報ConcurrentModificationException();異常的原因所在,請先看Itr的next()方法和next()調用的方法
     1//Itr的next方法:
     2public E next() {
     3
                checkForComodification();
     4        try 
    {
     5        E next =
     get(cursor);
     6        lastRet = cursor++
    ;
     7        return
     next;
     8        }
     catch(IndexOutOfBoundsException e) {
     9
            checkForComodification();
    10        throw new
     NoSuchElementException();
    11        }

    12    }

    13
    14//checkForComodification()方法:

    15final void checkForComodification() {
    16        if (modCount !=
     expectedModCount)
    17        throw new
     ConcurrentModificationException();
    18    }

    19    }
    20
        在next方法的一開始顯示調用了checkForComodification()方法(見第三行),在checkForComodification()方法中做的工作就是比較expectedModCount 和modCount的值是否相等,如果不相等,就認為還有其他對象正在對當前的List進行操作,那個就會拋出ConcurrentModificationException異常。
           經過以上的分析,發現拋出ConcurrentModificationException異常處于調用next()方法時,比較expectedModCount 和modCount的值,如果兩個值不相等,就會拋出異常,然而在什么情況下會使expectedModCount 和modCount的值不相等呢,只有在兩個Itr同時對一個list進行操作的時候才會出現這樣的問題,所以在以后的編碼過程中在是由Iterator進行remove()時一定要考慮是否時多線程的,如果是請不要用Iterator進行remove(),而應該使用List的remove方法進行。

    posted on 2008-04-01 09:56 linda 閱讀(4438) 評論(3)  編輯  收藏

    評論

    # re: 在多線程的情況下是由Iterator遍歷修改集合對象,報ConcurrentModificationException()異常的根因分析。 2009-03-27 23:02 梅友龍

    好內容,這個說法我接受,謝了  回復  更多評論   

    # re: 在多線程的情況下是由Iterator遍歷修改集合對象,報ConcurrentModificationException()異常的根因分析。 2009-03-27 23:03 梅友龍

    我比較喜歡研究技術的技術人,有時間可以聊聊~~  回復  更多評論   

    # re: 在多線程的情況下是由Iterator遍歷修改集合對象,報ConcurrentModificationException()異常的根因分析。[未登錄] 2012-02-09 12:46 Jack

    "如果是請不要用Iterator進行remove(),而應該使用List的remove方法進行。 "
    說反了吧?  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    <2008年4月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    統計

    常用鏈接

    留言簿(1)

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 一区二区三区免费视频网站| 白白色免费在线视频| 久久久精品午夜免费不卡| 久久久久亚洲爆乳少妇无| 精品无码国产污污污免费网站国产| 免费人成视频x8x8入口| 极品美女一级毛片免费| 亚洲乱码中文字幕综合234| 成年网站免费入口在线观看| www.亚洲色图| 99久久99这里只有免费的精品| 在线A亚洲老鸭窝天堂| 免费人成在线观看网站| 亚洲国产精品久久丫| 成人免费无码大片A毛片抽搐色欲 成人免费无码大片a毛片 | 污污网站18禁在线永久免费观看| 久久亚洲高清观看| 亚欧在线精品免费观看一区| 亚洲乱亚洲乱妇无码| 亚洲AV无码一区二区三区国产 | 美女18一级毛片免费看| 国产亚洲精品无码专区| 在线观看永久免费| 亚洲欧美日韩国产成人| 亚洲精品视频在线观看你懂的| 99免费在线视频| 亚洲福利一区二区精品秒拍| 免费黄色一级毛片| 任你躁在线精品免费| jlzzjlzz亚洲jzjzjz| 亚洲视频在线观看免费| 18禁免费无码无遮挡不卡网站| 亚洲AV无码AV日韩AV网站| 国产亚洲精品高清在线| 青青青国产在线观看免费网站| 在线91精品亚洲网站精品成人| 亚洲人成网77777色在线播放| 噼里啪啦电影在线观看免费高清 | 国内免费高清在线观看| 一级有奶水毛片免费看| 亚洲国产成人手机在线电影bd|