내 문제를 제공한다. java-doc은이 컨테이너가 fail-fast 반복기만을 제공한다고 말합니다. 그 Iterator
동안 제거 된 요소가있는 경우는 자바 컨테이너가 페일 세이프 (fail-safe) 반복자 여기
유효하지 않는 나에게 Iterator
을 제공 자바 Vector
또는 List
같은 표준 컨테이너를 통해 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);
}
}
문제는 벡터를 사용하여 시작합니다. 벡터는 사용하지 마십시오. 목록, 벡터 및 해시 테이블은 나쁜 연습이고 오래되었습니다. java.util.concurrent 패키지를 참조하십시오. –
@fuzzy :'Vector'와'Hashtable'은 반드시 나쁜 것은 아닙니다. 특정 기능 (대부분 동기화)이 필요할 때 유효한 위치가 있습니다. –
@joachim 그래서 퍼지가 이미 말했듯이 java.util.concurrent 패키지가있는 것입니다. CopyOnWriteArrayList는 동시 수정을 처리해야 할 때 매우 유용합니다. -* edit * : 기본적으로 List/Map/Set/등의 동기화 사본을 만드는 java.util.Collections.synchronizedXYZ 메소드가 있습니다. 스레드 세이프 래퍼를 사용하는 스레드 안전 목록 또는 맵이 필요한 경우에도 – Tedil