在服务器向客户端提供现有集合的不可修改集合的场景中,客户端开始对其进行迭代,同时如果在服务器级别一个线程更改列表,例如删除它的一个元素。这会导致客户异常吗?如果是,那会是什么?当客户端在迭代列表时突然出现异常时,这不是很奇怪吗?
3 回答
首先,它可能依赖于一个集合,因为它没有在内部Collection
或Collections
类的任何地方指定。
其次,测试起来非常简单。
public class CollectionModTest {
public static void main(String[] args) {
Collection<String> original = new HashSet<String>();
original.add("1");
original.add("2");
original.add("3");
original.add("4");
int counter= 5;
Collection<String> unmodifiable = Collections.unmodifiableCollection(original);
for (String val: unmodifiable) {
System.out.println(val);
original.add(""+counter);
counter++;
}
}
}
只需将Collection
实现替换为您使用的实现,并确定它是否会引发异常。
一旦您创建了一个不可修改的视图,IMO的一个好的做法就是丢失原始集合引用。这样,您将永远不必担心同时修改集合,因为您将永远无法做到。或者,如果您之后必须修改原始集合,您可以简单地创建集合的副本并对其进行迭代。然后可以在任何地方同时修改原始集合。关键部分将与新(副本)集合创建一样短。
客户端无法更改unmodifiableCollection
,因此不允许删除unmodifiableCollection
。
首先取决于是什么client
。如果客户端通过网络或其他方式接收到集合,则服务器端集合上的更改不会更改客户端的集合,因为它是不同 JVM 上的不同对象。
如果服务器和客户端都在同一个 JVM 中引用同一个对象,那么这取决于客户端如何迭代。
如果客户端这样做:
for(int i = 0;i < col.size();i++) { col.get(i);}
那么它不会导致错误。
如果客户端使用for(Object o : col)
或者如果客户端直接使用 Iterator,那么您将ConcurrentModificationException
尽最大努力获得大部分时间。