2011-05-19 61 views
7

我工作的一段代碼與迭代並獲得在該行一個一個ConcurrentModificationException的,當我從我的IDE上windows--拋出ConcurrentModificationException的系統依賴

LinkedList ll =new LinkedList(); 
    . . . 
    . . . 
    Iterator iter = ll.iterator(); 
    int i=0; 
    while (iter.hasNext()) { 
     // GrammarSection agrammarSection = (GrammarSection) iter.next(); //a 
     String s1 = (String) iter.next(); 
     ll.remove(i); 
     i++; 
    } 

這是預期運行的程序,因爲林在迭代時修改列表,以便快速迭代器引發併發修改異常。但是,當我用apache服務器在unix中運行此代碼時,迭代器的下一個方法不會拋出任何異常。那麼,併發修改異常是否取決於操作系統級別?

+0

您確定您的JDK,代碼和數據在兩種環境中都相同嗎?我很抱歉,但我不相信這是可能的。 Java是跨平臺的。 ConcurrentModificationException是從集合中拋出的,也就是從java本身寫成的JDK拋出,所以不能依賴於平臺。 – AlexR 2011-05-19 15:25:02

+0

你應該接受以前的答案.. – 2011-05-19 15:25:33

回答

3

不,不應該。無論如何,它應該會崩潰。

我猜想它可能在不同的JVM上有所不同,但根據official spec,鏈表上的迭代器應該是快速失敗的。

操作系統與它無關。

1

我發現問題可能是什麼。當你的清單有2個元素時,hasNext()返回false,它沒有例外。如果列表包含3個或更多元素,則它會在每個地方引發異常。所以請確保您的列表中包含正確數量的元素。

對於OS依賴性 - java代碼是不依賴於操作系統的

反正 - 使用iter.remove() - 它會從底層列表中刪除元件,而不會引起異常。

您的方法存在的問題是您正在修改底層列表,而無需迭代器知道該修改的任何內容。所以你必須通過迭代器來執行它。

+1

這是一個評論,而不是一個答案...... OP的問題是,如果投擲,或不是,CoMo是OS特定的。對我來說是一個非常酷的問題:) – SyntaxT3rr0r 2011-05-19 15:19:58

+0

是的,我現在有一段關於這個。 – Bozho 2011-05-19 15:21:14

0

使用iter.remove();不會ll.remove(i)

如果您使用迭代器刪除功能,您將不會得到併發修改忽略。

但是,要回答你的問題; CME不應該依賴操作系統級別。您的代碼必須存在其他一些問題,爲什麼它不會將unix中的CME引入其中。

BTW,該規範有以下評論

「注意,迭代器的快速失敗行爲不能得到保證,一般來說,不可能作出任何硬性保證不同步併發修改的存在。失敗快速迭代器會盡可能拋出ConcurrentModificationException,因此,編寫一個依賴於此異常的程序是正確的,這將是錯誤的:迭代器的失敗 - 快速行爲應該只用於檢測錯誤。

+0

我非常清楚爲什麼這個例外即將到來以及它如何被移除。我的問題是爲什麼我在Unix環境下運行時沒有得到異常? – user496934 2011-05-19 15:21:37

+0

我的問題是併發修改異常取決於操作系統級別? – user496934 2011-05-19 15:22:18

+0

答案是否定的。必須有其他一些因素導致CME不能在unix env中拋出。 – 2011-05-19 15:24:59

0

那麼,併發修改 異常依賴於操作系統級別?

它確實有一些JMV依賴性,但不是在您顯示的代碼中。

// LinkedLists have a member variable called modCount 
// which is an integer which holds the count of modifications 
// made on the list with methods like list.add() list.remove() etc. 
LinkedList ll =new LinkedList(); 
. . . 
. . . 
// When the iterator is created here, it copies the current modCount 
// of the LinkedList into a member of its own called expectedModCount 
Iterator iter = ll.iterator(); 
int i= 0; 
while (iter.hasNext()) { 
    // iter.next() calls a method called checkForComodification 
    // which throws a ConcurrentModificationException if the 
    // current modCount of the original LinkedList is different 
    // from the expectedModCount on this iterator 
    String s1 = (String) iter.next(); 
    ll.remove(i); 
    i++; 
} 

當列表被訪問和不正確的同步在不同的線程迭代,以LinkedList.modCount進行的修改(當LinkedList.addLinkedList.remove等的稱呼)可能不是線程做迭代可見。所以ConcurrentModificationException一般不保證被拋出。但是在你顯示的單線程代碼中,應該沒有可見性問題,並且如果在ll.iterator()之後成功調用了ll.remove(),則應始終引發異常。