2013-08-20 35 views
0

我有如下我的代碼和我得到ConcurrentModificationException的,尤其是在(String一個文件:文件)行ConcurrentModificationException的在HashSet的

做迭代的時候,不更改「文件」什麼,所以爲什麼會導致異常,我應該如何避免它?感謝您的任何建議!

int getTotalLength(final HashSet<String> files) { 
     int total = 0; 
     int len; 
     for (String file : files) { 
      len = getLength(file); 
      if (len != Long.MIN_VALUE) { 
       total += len; 
      } 
     } 
     return total; 
    } 




     int getLength(String file) { 
     int len = Long.MIN_VALUE; 

     if (file == null) { 
      return len; 
     } 

     File f = new File(file); 

     if (f.exists() && f.isFile()) { 
      len = f.length(); 
     } 

     return size; 
    } 
+1

那麼你有任何其他線程,可能會在同一時間修改集? –

+0

是的,這是可能的,但我已經使hashSet最終...不會阻止該設置被修改? –

+0

ConcurrentModification在你的HashSet上,而不在你的文件上 –

回答

3

指的你對此有何評論,聲明final HashSet<String> files使得可變files結局 - 這意味着你不能在另一個對象賦給這個變量的作用域內部的變量。 HashSet本身是可變對象,可以修改 - 它與final修飾符無關(引用setsel對象itselt仍然相同)。 如果您想在同一個對象(相同的哈希集)上一致地使用​​塊或方法。

一般而言,您不能修改在for-each類似變體中使用for循環進行迭代的集合(在相同或另一個線程中)。

+0

調用者(比如,callerA)調用getTotalLength()是一個已經同步方法和callerA不修改的集合,但callerB調用callerA修改收集... 代碼看起來像這樣 無效callerB (){修改HashSet; callerA(); } 空隙callerA(){ 調用getTotalLength()其中,i得到的異常 } –

+0

我應該使用同步塊在呼叫者乙使得 空隙callerB(){ 同步(HashSet中){ 修改的HashSet ; callerA()它迭代hashSet; } } –

+0

如果該方法(如同您所說的「同步方法」)是同步的,這意味着如果一個線程正在執行此類方法(在其「內部」),則不允許另一個線程執行該方法,直到之前的執行結束。如果已經同步了兩種不同的方法(在方法簽名中使用'synchronized'關鍵字),它們不會彼此同步。您必須將您的通用對象上的代碼顯式同步到兩個要同步的方法。 – Antoniossss