Reputation: 1760
If I have a synchronized collection like this
Collection c = Collections.synchronizedCollection(myCollection);
javadoc for the synchronizedCollection
mentiones that external iteration must be synchronized like this :
synchronized (c) {
Iterator i = c.iterator();
while (i.hasNext()) {
process (i.next());
}
}
Can I assume that c.toArray()
is synchronized and therefore no changes to the collection will happen when the method executes?
Or do I need to synchronize it as well:
synchronized (c) {
c.toArray();
}
Upvotes: 7
Views: 1468
Reputation: 24336
There seems to a be a large misconception going on here that you can rely on the actual source code implementation. This is false, you must rely on the contract of the method. Since the contract does not exist you cannot assume it will do something, at any point in time the underlying implementation can change. For instance look at the following function:
/**
* Returns an empty Collection of Books.
*
*
* /
public Collection returnEmptyBooks()
{
return new HashSet<Book>();
}
This implies I can return anything that implements the Collection interface. Signature plus documentation. You could not assume that it is synchronized or anything else of that nature. You could also deduce that you will not ever get null back from this method, unless the contract has been violated.
In case no one reads the comments. Any conversion from one data structure to another implies iteration. You cannot move from List to Set without iterating over all of the elements. The same would apply with a conversion to an Array. You must fill the Array by iterating over your initial data structure, therefore it needs to be synchronized.
Upvotes: 0
Reputation: 500893
From the Javadoc for synchronizedCollection
:
Returns a synchronized (thread-safe) collection backed by the specified collection.
Thus, c.toArray()
does not require any additional synchronization. SynchronizedCollection
's toArray()
method will do the locking for you. In essence, that's the whole point of synchronizedCollection()
.
If you want to confirm that this reading of the contract agrees with the actual implementation, see GrepCode.
Upvotes: 5
Reputation: 1426
If you are using java.util.Collections which is part of the standard Java Collection API, then all methods on the returned SynchronizedCollection is synchronized including toArray(). See code blocks below, taken from Java source code in java.util.Collections.SynchronizedCollection.
public Object[] toArray() {
synchronized(mutex) {return c.toArray();}
}
public <T> T[] toArray(T[] a) {
synchronized(mutex) {return c.toArray(a);}
}
Upvotes: 0
Reputation: 11194
You don't need it, the method performs the synchronization for you.
Upvotes: 1
Reputation: 15229
If you're talking about Apache's commons collection utility the answer is yes. CollectionUtils.synchronizedCollection(...)
returns an instance of SynchronizedCollection
who's toArray()
method is:
public Object[] toArray() {
synchronized (lock) {
return collection.toArray();
}
}
Upvotes: 2