是同步Collection的toArray()方法同步?

时间:2012-02-23 13:46:55

标签: java collections synchronized

如果我有像这样的同步集合

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();
}

5 个答案:

答案 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。转换为数组也是如此。您必须通过迭代初始数据结构来填充数组,因此需要进行同步。