使类上的所有方法单独同步不会使这些方法的聚合(在组中调用它们)成为线程安全的。通过将 包装Iterator
在一个同步块中,您可以保护迭代器的特定实例,使其不被多个线程调用的单个方法与其他调用穿插。
如果我.add()
在安全的情况下调用一次,如果我需要.add()
多次调用以完成一个逻辑语句,则不能保证其他人没有在我的.add()
调用之间添加其他内容或删除其他内容,除非我阻止其他所有内容调用.add()
(或任何其他方法)通过synchronizing
代表集合的变量。
对集合上的Iterator
各个方法进行多次调用,它们都必须包装在一个synchronized
块中,以使它们作为单一transaction
的一种执行。检查执行的源代码 Iterator
你会明白我的意思。这是List
它对底层实现进行多次单独调用的源代码,因此它们都需要由同一线程以不间断的顺序执行才能确定。
@Override
public Iterator<A> iterator() {
if (tail == null)
return emptyIterator();
return new Iterator<A>() {
List<A> elems = List.this;
public boolean hasNext() {
return elems.tail != null;
}
public A next() {
if (elems.tail == null)
throw new NoSuchElementException();
A result = elems.head;
elems = elems.tail;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
源代码显示AbstractList.iterator()
了更复杂的逻辑,可以进行多次调用。
更好的包装器是将它们包装在Immutable
集合中,然后您保证没有其他东西可以改变调用之间的基础集合。