2013-03-15 114 views
8

我在這裏問一個問題關於迭代一個Vector,我已經回答了一些很好的解決方案。但我讀了另一種更簡單的方法來做到這一點。我想知道這是不錯的解決方案。遍歷集合同步

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next().draw(g); 
} 

mapItems是一個同步集合:Vector。爲使在Vector安全從ConcurrentModificationException了反覆?

+1

你有任何正確的答案接受?? – AmitG 2013-04-05 07:15:22

回答

3

是的,它將使安全起始於ConcurrentModificationException,代價是一切基本上都是單線程的。

2

是的,我認爲,這將阻止ConcurrentModificationException。您正在同步Vector。該修改它Vector所有方法也​​,這意味着他們也將鎖定同一個對象。所以當你迭代它時,沒有其他線程可以改變Vector

而且,你自己都沒有修改Vector當你迭代它。

1

你可能要考慮使用ReadWriteLock中。

對於遍歷列表而不修改其內容的進程,獲取共享ReentrantReadWriteLock的讀鎖定。這允許多個線程對鎖具有讀取訪問權限。

對於將修改列表的進程,獲取共享鎖上的寫入鎖定。這將阻止所有其他線程訪問列表(甚至是隻讀),直到您釋放寫入鎖定。

1

這是否使從Vector的安全迭代 ConcurrentModificationException?

它使從ConcurrentModificationException安全的迭代過向量。如果它不是在這種情況下再同步的,如果你是通過不同的線程訪問Vector和在任何其他線程在結構上修改矢量迭代器創建後的迭代器會拋出ConcurrentModificationException。 考慮在運行此代碼:

import java.util.*; 
class VVector 
{ 
    static Vector<Integer> mapItems = new Vector<Integer>(); 
    static 
    { 
     for (int i = 0 ; i < 200 ; i++) 
     { 
      mapItems.add(i); 
     } 
    } 
    public static void readVector() 
    { 
     Iterator<Integer> iterator = mapItems.iterator(); 
     try 
     { 
      while(iterator.hasNext()) 
      { 
       System.out.print(iterator.next() + "\t"); 
      } 
     } 
     catch (Exception ex){ex.printStackTrace();System.exit(0);} 
    } 
    public static void main(String[] args) 
    { 
     VVector v = new VVector(); 
     Thread th = new Thread(new Runnable() 
     { 
      public void run() 
      { 
       int counter = 0; 
       while (true) 
       { 
        mapItems.add(345); 
        counter++; 
        if (counter == 100) 
        { 
         break; 
        } 
       } 
      } 
     }); 
     th.start(); 
     v.readVector(); 

    } 
} 

在我的系統中,它顯示下面的輸出,同時執行:

0  1  2  3  4  5  6  7  8  9 
java.util.ConcurrentModificationException 
     at java.util.AbstractList$Itr.checkForComodification(Unknown Source) 
     at java.util.AbstractList$Itr.next(Unknown Source) 
     at VVector.readVector(VVector.java:19) 
     at VVector.main(VVector.java:38) 

但在另一方面,如果你做的含Iterator訪問Vector代碼塊同步使用mapItems作爲鎖,它將阻止執行與Vector相關的其他方法,直到​​塊完全原子化。

2

簡單地同步整個集合不會阻止ConcurrentModificationException。這仍然會拋出CME

synchronized(mapItems) { 
    for(MapItem item : mapsItems){ 
     mapItems.add(new MapItem()); 
    } 
} 
0

如果我們在while循環內調用add方法然後拋出異常。

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next(); 
     mapItems.add("Something"); // throws ConcurrentModificationException 
}