这个问题相当老了(对不起,我有点晚了..)但我仍然想添加我的答案。
我会选择您的第二个选择(即在调用 iterator() 之前克隆集合),但有一个重大转折。
假设,你想使用迭代器进行迭代,你不必在调用 .iterator() 之前复制 Collection 并且有点否定(我松散地使用术语“否定”)迭代器模式的想法,但你可以写一个“线程安全迭代器”。
它将在相同的前提下工作,复制集合,但不让迭代类知道,你就是这样做的。这样的迭代器可能如下所示:
class ThreadSafeIterator<T> implements Iterator<T> {
private final Queue<T> clients;
private T currentElement;
private final Collection<T> source;
AsynchronousIterator(final Collection<T> collection) {
clients = new LinkedList<>(collection);
this.source = collection;
}
@Override
public boolean hasNext() {
return clients.peek() != null;
}
@Override
public T next() {
currentElement = clients.poll();
return currentElement;
}
@Override
public void remove() {
synchronized(source) {
source.remove(currentElement);
}
}
}
更进一步,您可能会使用Semaphore
Class 来确保线程安全或其他东西。但是采取带有一粒盐的去除方法。
关键是,通过使用这样的迭代器,没有人,无论是迭代还是被迭代的类(这是一个真正的词)都不必担心线程安全。