难道一个Java容器,提供故障安全迭代器
题
下面是我的问题:
这一段代码抛出一个java.util.ConcurrentModificationException
,因为虽然存在用于此数据结构的Vector
的listeners
Iterator
被修改。
在java-doc的说,这个容器仅提供了快速失败的迭代器。
有没有一种可能超过象Java Iterator
或Vector
标准容器得到一个List
这为我提供了一个Iterator
,不得到无效的(不是快速失败的),如果存在Iterator
中删除元素“生活“?
我应该像在C ++中std::list
相同的行为。有迭代器,即使当前迭代器删除始终有效。比迭代器被设置为在列表中的下一个元素。
public class ClientHandle {
private final Vector<ClientHandleListener> listeners = new Vector<ClientHandleListener>();
public synchronized void addListener(ClientHandleListener chl) {
listeners.add(chl);
}
public synchronized void removeListener(ClientHandleListener chl) {
listeners.remove(chl);
}
private void fireConnectionClosed() {
final ClientHandle c = this;
final Iterator<ClientHandleListener> it = listeners.iterator();
new Thread(){
@Override
public void run() {
while (it.hasNext()) {
it.next().connectionClosed(c); //FIXME the iterator gets modified
}
};
}.start();
}}
public class ClientHandlePool implements ClientHandleListener, TaskManagerListener {
/*...*/
public synchronized void removeClientHandle(ClientHandle ch) {
//here the listeners Vector from the ClientHandle gets modified
ch.removeListener(this);
ch.removeListener(currentListener);
clientHandles.remove(ch);
}
@Override
public void connectionClosed(ClientHandle ch) {
removeClientHandle(ch);
}
}
解决方案
据我知道有没有办法追溯添加能力,任何默认Collection
实现(Iterable
其实)。
但也有实施方式的支持,通过具有并发修改定义良好的响应,而迭代样的行为。
一个例子是 CopyOnWriteList
一>
其他提示
在听众的情况下,你可能会考虑使用java.util.concurrent.CopyOnWriteArrayList
,你通常有更多的方式读比写。
看看java.util.concurrent包,你会发现你所需要的一切。
一个懒惰的方式来创建一个快捷,故障安全迭代:取列表的副本作为一个阵列,同时在锁定和foreach()在阵列上同时解锁...可以与任何类型的列表完成p>
private void fireConnectionClosed() {
final ClientHandle c = this;
final ClientHandleListener[] listenersArr;
synchronized(this) {
listenersArr=listeners.toArray(new ClientHandleListener[0]);
}
new Thread(){
@Override
public void run() {
for(ClientHandleListener listener : listenersArr )
listener.connectionClosed(c);
}
};
}.start();
}
不隶属于 StackOverflow