Java 同步收集
因为c已经是同步的集合,所以它是线程安全的。但是为什么我们必须在迭代中再次使用Java 同步收集,java,loops,synchronized,Java,Loops,Synchronized,因为c已经是同步的集合,所以它是线程安全的。但是为什么我们必须在迭代中再次使用synchronized(c)?真的很困惑。谢谢 “用户必须手动同步返回的数据 在集合上迭代时: Collection c = Collections.synchronizedCollection(myCollection); ... synchronized(c) { Iterator i = c.iterator(); // Must be in the synchronized block
synchronized(c)
?真的很困惑。谢谢
“用户必须手动同步返回的数据
在集合上迭代时:
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext()) {
foo(i.next());
}
}
不遵循此建议可能会导致不确定性行为。”
。但是迭代必然涉及多个单独的方法调用,所以您,同步集合的用户,必须自己同步整个迭代
例如,如果没有在
c
上进行同步,则集合的内容可能会在i.hasNext()
和i.next()
之间发生变化,甚至可能从有元素变为没有更多元素,在这种情况下,i.next()
将失败。单独同步类上的所有方法不会使这些方法的聚合(在组中调用它们)成为线程安全的。通过将迭代器
包装在一个同步块中,您可以保护迭代器的特定实例,使其单个方法的调用不会与多个线程的其他调用混杂在一起
如果我在安全的情况下调用.add()
,如果我需要多次调用.add()
来完成一个逻辑语句,则不能保证其他人没有在我的.add()
调用之间添加或删除其他内容,除非我阻止其他所有调用.add()
(或任何其他方法)对表示集合的变量进行同步
Iterator
对集合中的各个方法进行多次调用,它们都必须包装在一个synchronized
块中,以使它们作为单个事务执行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()
的公共迭代器显示了进行多次调用的更复杂的逻辑
更好的包装器是将它们包装在不可变的集合中,然后您可以保证其他任何东西都不能改变调用之间的基础集合。您所说的“必然涉及多个单独的方法调用”是什么意思?@user697911:i.hasNext()
和i.next()
是两个独立的方法调用,无法实现集合。synchronizedCollection
可确保i.hasNext()和i.next()之间没有任何更改
。那么,concurrentHashmap将是相同的吗?我们还必须在迭代中同步concurrenthashamp吗?不,您永远不需要同步concurrentHashmap
。CHM的文档声明:“视图的迭代器是”弱一致的“迭代器不会抛出ConcurrentModificationException,并保证遍历迭代器构造时存在的元素,并且可能(但不保证)反映构造后的任何修改。"换句话说,ConcurrentHashMap
使用一个专门的实现,确保在迭代过程中修改映射时,其迭代器不会爆炸,并且这些迭代器可能考虑也可能不考虑进一步的修改。ConcurrentHashMap
可以做类似的事情,因为并发是从头开始构建的;集合。synchronizedCollection
只能为通常不并发的集合提供一个简单的包装。这是我遇到的最好的解释!