迭代同步集合

时间:2013-03-15 17:48:53

标签: java multithreading vector synchronized

我在这里问了一个关于迭代Vector的问题,我已经得到了一些很好的解决方案。但我读到了另一种更简单的方法。我想知道这是否是一个很好的解决方案。

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

mapItems是一个同步集合:Vector。这是否使Vector安全地从ConcurrentModificationException安全?

6 个答案:

答案 0 :(得分:3)

是的,它会使ConcurrentModificationException安全,但代价是基本上是单线程的。

答案 1 :(得分:2)

是的,我相信这会阻止ConcurrentModificationException。您正在Vector上进行同步。 Vector上修改它的所有方法也是synchronized,这意味着它们也会锁定同一个对象。因此,当您迭代它时,没有其他线程可以更改Vector

此外,您在迭代时不会自己修改Vector

答案 2 :(得分:2)

简单地同步整个集合不会阻止ConcurrentModificationException。这仍将抛出一个CME

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

答案 3 :(得分:1)

您可能需要考虑使用ReadWriteLock。

对于迭代列表而不修改其内容的进程,在共享的ReentrantReadWriteLock上获取读锁定。这允许多个线程具有对锁的读访问权。

对于将修改列表的进程,获取共享锁上的写锁定。这将阻止所有其他线程访问列表(甚至是只读),直到您释放写锁定。

答案 4 :(得分:1)

  

这是否可以安全地迭代Vector   ConcurrentModificationException的?

它使从ConcurrentModificationException安全地迭代Vector。如果它不同步那么在这种情况下,如果你通过各种线程访问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的代码块使用Vector作为锁访问mapItems同步,则会阻止执行与{Vector相关的其他方法{1}}直到synchronized块以原子方式完成。

答案 5 :(得分:0)

如果我们在循环中调用add方法然后抛出异常。

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