8

ここで a の反復処理について質問したVectorところ、いくつかの適切な解決策が得られました。しかし、私はそれを行う別の簡単な方法について読みました。それが良い解決策かどうか知りたいです。

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

mapItems は同期コレクションです: Vector. Vectorそれはセーフからの反復を行いConcurrentModificationExceptionますか?

4

6 に答える 6

3

はい、ConcurrentModificationException基本的にすべてがシングルスレッドであるという犠牲を払って安全になります。

于 2013-03-15T17:55:41.970 に答える
2

コレクション全体を同期するだけでは、ConcurrentModificationExceptionを防ぐことはできません。これでもCMEがスローされます

synchronized(mapItems) {
   for(MapItem item : mapsItems){
      mapItems.add(new MapItem());
   }
}
于 2013-03-15T18:25:51.827 に答える
2

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

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

于 2013-03-15T17:58:17.840 に答える
1

ReadWriteLock の使用を検討することをお勧めします。

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

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

于 2013-03-15T18:15:19.907 に答える
1

ConcurrentModificationException から安全に Vector を反復処理できますか?

はい、Vector の反復を安全にしますConcurrentModificationException。同期されていない場合、さまざまなスレッドを介して Vector にアクセスしていて、イテレータが作成された後、他のスレッドが 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されたアクセスを含むコードのブロックを作成すると、その ブロックがアトミックに完了するまで、関連する他のメソッドの実行が妨げられます。VectormapItemsVectorsynchronized

于 2013-03-15T18:19:35.170 に答える
0

while ループ内で add メソッドを呼び出すと、例外がスローされます。

synchronized(mapItems) {
    Iterator<MapItem> iterator = mapItems.iterator();
    while(iterator.hasNext())
        iterator.next();
         mapItems.add("Something");  //  throws ConcurrentModificationException
}
于 2013-03-15T19:17:13.220 に答える