2013-03-15 20 views
8

私はVectorを反復することに関してここで質問しましたが、私はいくつかの良い解決法で答えられました。しかし、私はそれを行うためのもう一つの簡単な方法についてお読みになりました。私はそれが良い解決策であるかどうかを知りたい。同期コレクションの反復

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

mapItemsは同期化されたコレクションです。それはVectorを繰り返し、ConcurrentModificationExceptionから安全ですか?

+1

受け入れるための正解はありますか? – AmitG

答えて

3

はい、ConcurrentModificationExceptionから安全になりますが、本質的にすべてがシングルスレッドであることを犠牲にします。

2

はい、これはConcurrentModificationExceptionを防止すると考えています。 Vectorで同期しています。それを変更するVectorのすべてのメソッドも​​です。つまり、同じオブジェクトにもロックされます。他のスレッドでは、反復処理中にVectorを変更することはできません。

また、反復処理中にVectorを変更していません。

1

ReadWriteLockの使用を検討してください。

内容を変更せずにリストを反復処理するプロセスでは、共有ReentrantReadWriteLockで読み取りロックを取得します。これにより、複数のスレッドがロックへの読み取りアクセス権を持つことができます。

リストを変更するプロセスでは、共有ロックの書き込みロックを取得します。これにより、書き込みロックを解除するまで、ほかのすべてのスレッドがリストにアクセスできなくなります(読み取り専用でも)。

1

ベクターセーフの反復処理を から行いますか?ConcurrentModificationException?

YESあなたはさまざまなスレッドを経由してベクトルにアクセスしているといくつかの他のスレッドが構造的に任意のでベクトルを変更している場合には、そのような場合には、その後同期していない.IFそれはConcurrentModificationExceptionからベクトルの繰り返し処理を安全になりますイテレータが作成された後、イテレータは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) 

しかし、その一方で、あなたがそのVectorにアクセスするためにIteratorを含むコードのブロックを作る場合は、同期 このコードを実行している考えてみましょうmapItemsをロックとして使用すると、ブロック​​がアトミックに完了するまで、Vectorに関連する他のメソッドの実行を防止します。

2

単純にコレクション全体を同期しても、ConcurrentModificationExceptionが防止されるわけではありません。これによってCMEがスローされますが、whileループの中でaddメソッドを呼び出してから例外をスローすると、CMEがスローされます。

synchronized(mapItems) { 
    for(MapItem item : mapsItems){ 
     mapItems.add(new MapItem()); 
    } 
} 
0
synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next(); 
     mapItems.add("Something"); // throws ConcurrentModificationException 
} 
関連する問題