下面是我的问题:

这一段代码抛出一个java.util.ConcurrentModificationException,因为虽然存在用于此数据结构的Vectorlisteners Iterator被修改。 在java-doc的说,这个容器仅提供了快速失败的迭代器。

有没有一种可能超过象Java IteratorVector标准容器得到一个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()在阵列上同时解锁...可以与任何类型的列表

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();
}
scroll top