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

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

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

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

             在多線程下使用Iterator來(lái)迭代對(duì)象時(shí),總會(huì)包ConcurrentModificationException();異常,經(jīng)過(guò)我對(duì)list和Iterator相關(guān)源碼的分析,終于搞明白了這個(gè)問(wèn)題: 
             下面結(jié)合源代碼來(lái)討論這個(gè)問(wèn)題:

              1、當(dāng)我們調(diào)用一個(gè)List的iterator時(shí),其實(shí)返回的并不是Itr對(duì)象(Iterator是一個(gè)接口),請(qǐng)看代碼:
    1  public Iterator<E> iterator() {
    2    return new
     Itr();
    3  }
           
           2、在Itr類(lèi)中有這么一句話  int expectedModCount = modCount;首先講一下這兩個(gè)變量的含義:
                 expectedModCount :創(chuàng)建當(dāng)前的Itr對(duì)象時(shí)集合對(duì)象被修改的次數(shù)。他是Itr的變量。
                 modCount:記錄集合對(duì)象從創(chuàng)建到當(dāng)前時(shí)間被做修改的次數(shù)。(集合每進(jìn)行一次增刪改查都會(huì)使modCount),他是Itr的外部類(lèi)AbstractList
                 的變量,且該變量在 AbstractList中被如此修飾protected transient int modCount = 0; 
                另外,Itr自己對(duì)集合對(duì)象進(jìn)行了修改后,他會(huì)維持expectedModCount 和modCount的保持相等,請(qǐng)看以下代碼
     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的值發(fā)生了改變嗎,他改變了,帶代碼的第8行改變的,請(qǐng)看此處的代碼:
             
     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發(fā)生了改變。 由此可以看出,在我們調(diào)用集合對(duì)象的iterator()方法的remove時(shí)總會(huì)使list的modCount的值自增1,但是Itr會(huì)自己維護(hù)該值和expectedModCount 的一致。
           3、試問(wèn):如果expectedModCount 和modCount的值如果不相等,會(huì)有什么問(wèn)題呢,這就是報(bào)ConcurrentModificationException();異常的原因所在,請(qǐng)先看Itr的next()方法和next()調(diào)用的方法
     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方法的一開(kāi)始顯示調(diào)用了checkForComodification()方法(見(jiàn)第三行),在checkForComodification()方法中做的工作就是比較expectedModCount 和modCount的值是否相等,如果不相等,就認(rèn)為還有其他對(duì)象正在對(duì)當(dāng)前的List進(jìn)行操作,那個(gè)就會(huì)拋出ConcurrentModificationException異常。
           經(jīng)過(guò)以上的分析,發(fā)現(xiàn)拋出ConcurrentModificationException異常處于調(diào)用next()方法時(shí),比較expectedModCount 和modCount的值,如果兩個(gè)值不相等,就會(huì)拋出異常,然而在什么情況下會(huì)使expectedModCount 和modCount的值不相等呢,只有在兩個(gè)Itr同時(shí)對(duì)一個(gè)list進(jìn)行操作的時(shí)候才會(huì)出現(xiàn)這樣的問(wèn)題,所以在以后的編碼過(guò)程中在是由Iterator進(jìn)行remove()時(shí)一定要考慮是否時(shí)多線程的,如果是請(qǐng)不要用Iterator進(jìn)行remove(),而應(yīng)該使用List的remove方法進(jìn)行。

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

    評(píng)論

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

    好內(nèi)容,這個(gè)說(shuō)法我接受,謝了  回復(fù)  更多評(píng)論   

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

    我比較喜歡研究技術(shù)的技術(shù)人,有時(shí)間可以聊聊~~  回復(fù)  更多評(píng)論   

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

    "如果是請(qǐng)不要用Iterator進(jìn)行remove(),而應(yīng)該使用List的remove方法進(jìn)行。 "
    說(shuō)反了吧?  回復(fù)  更多評(píng)論   


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


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

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

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 扒开双腿猛进入爽爽免费视频| 国产午夜亚洲精品不卡免下载 | 久久国产亚洲精品| 亚洲精品在线免费观看视频| 久久青草亚洲AV无码麻豆| 9久久免费国产精品特黄| 亚洲熟伦熟女新五十路熟妇| 日韩在线视频免费| 亚洲国产人成精品| yy一级毛片免费视频| 亚洲精品第一国产综合精品99| 羞羞视频免费网站入口| 亚洲国产V高清在线观看| 男女啪啪免费体验区| 亚洲精品成人久久久| 福利免费在线观看| 亚洲电影国产一区| 69av免费视频| 亚洲人成人伊人成综合网无码| 国产免费牲交视频| 黄色网页在线免费观看| 久久久久久亚洲精品中文字幕| 在线成人爽a毛片免费软件| 激情综合亚洲色婷婷五月APP| 成年人视频在线观看免费| 特级毛片aaaa级毛片免费| 久久亚洲欧洲国产综合| 青青草无码免费一二三区| 精品亚洲AV无码一区二区三区 | 亚洲欧洲日韩极速播放| 免费h黄肉动漫在线观看| 中文字幕不卡高清免费| 亚洲日产2021三区在线 | 美女被cao免费看在线看网站| 在线精品自拍亚洲第一区| 亚洲日韩国产精品第一页一区| 18级成人毛片免费观看| 亚洲av无码专区在线电影天堂| 国产成人精品日本亚洲专区61| 久久福利资源网站免费看| 黄页网站在线视频免费|