如果我有像这样的同步集合
Collection c = Collections.synchronizedCollection(myCollection);
synchronizedCollection
的javadoc提到外部迭代必须像这样同步:
synchronized (c) {
Iterator i = c.iterator();
while (i.hasNext()) {
process (i.next());
}
}
我可以假设c.toArray()
已同步,因此在方法执行时不会对集合进行任何更改吗?
或者我也需要同步它:
synchronized (c) {
c.toArray();
}
答案 0 :(得分:5)
来自synchronizedCollection
的{{3}}:
返回由指定集合支持的同步(线程安全)集合。
因此,c.toArray()
不需要任何额外的同步。 SynchronizedCollection
的{{1}}方法会为您锁定。从本质上讲,这是toArray()
的全部要点。
如果您想确认此合同读数与实际实施一致,请参阅Javadoc。
答案 1 :(得分:2)
如果你在谈论Apache的commons集合实用程序,答案是肯定的。 CollectionUtils.synchronizedCollection(...)
会返回SynchronizedCollection
toArray()
方法的实例:
public Object[] toArray() {
synchronized (lock) {
return collection.toArray();
}
}
答案 2 :(得分:1)
您不需要它,该方法为您执行同步。
答案 3 :(得分:0)
如果您使用的是作为标准Java Collection API一部分的java.util.Collections,则会同步返回的SynchronizedCollection上的所有方法,包括toArray()。请参阅下面的代码块,它取自java.util.Collections.SynchronizedCollection中的Java源代码。
public Object[] toArray() {
synchronized(mutex) {return c.toArray();}
}
public <T> T[] toArray(T[] a) {
synchronized(mutex) {return c.toArray(a);}
}
答案 4 :(得分:0)
这里似乎存在一个很大的误解,你可以依赖实际的源代码实现。这是假的,你必须依赖方法的合同。由于合同不存在,你不能假设它会做任何事情,在任何时候底层实施都可以改变。例如,查看以下函数:
/**
* Returns an empty Collection of Books.
*
*
* /
public Collection returnEmptyBooks()
{
return new HashSet<Book>();
}
这意味着我可以返回任何实现Collection接口的东西。签名加文档。你无法假设它是同步的或其他任何性质的。除非合同被违反,否则您还可以推断出您不会从此方法返回null。
如果没有人阅读评论。从一个数据结构转换到另一个数据结构意味着迭代。如果不迭代所有元素,则无法从List移动到Set。转换为数组也是如此。您必须通过迭代初始数据结构来填充数组,因此需要进行同步。