我在这里问了一个关于迭代Vector
的问题,我已经得到了一些很好的解决方案。但我读到了另一种更简单的方法。我想知道这是否是一个很好的解决方案。
synchronized(mapItems) {
Iterator<MapItem> iterator = mapItems.iterator();
while(iterator.hasNext())
iterator.next().draw(g);
}
mapItems是一个同步集合:Vector。这是否使Vector
安全地从ConcurrentModificationException
安全?
答案 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
}