Вот моя проблема:ли контейнер Java предлагает отказоустойчивую итератор
Этот фрагмент кода бросает java.util.ConcurrentModificationException
, потому что Vector
listeners
изменяется, пока существует Iterator
для этой структуры данных. В java-doc говорится, что этот контейнер предлагает только отказоустойчивый итератор.
Есть ли возможность получить Iterator
через стандартный контейнер, как Vector
или List
в Java, который предлагает мне Iterator
, которая не получает недействительный (не обязательно-быстро), если существует элемент удаляется во что Iterator
"жизни"?
Я должен иметь такое же поведение, как std::list
в C++. Там итератор всегда действует, даже если текущий итератор удален. Чем итератор установлен на следующий элемент в списке.
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);
}
}
Ваша проблема заключается в использовании вектора для начала, не используйте Векторное использование списка, векторов и хэш-таблиц - это обычная практика и старые. См. Пакет java.util.concurrent. –
@fuzzy: 'Vector' и' Hashtable' не обязательно плохие. Когда вам нужны их специфические функции (в основном синхронизация), тогда у них есть действующее место. –
@joachim Ну, вот почему пакет java.util.concurrent, как уже говорилось, нечеткое. CopyOnWriteArrayList очень полезен, когда вам приходится иметь дело с одновременными изменениями. * edit *: Кроме того, существуют также методы java.util.Collections.synchronizedXYZ, которые в основном создают синхронизированную копию вашего списка/карты/набора/etc ... Вам все равно придется использовать синхронизированные блоки, хотя – Tedil