artur
artur

Reputation: 1760

is synchronized Collection's toArray() method synchronized?

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

Answers (5)

Woot4Moo
Woot4Moo

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

NPE
NPE

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

IceMan
IceMan

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

MahdeTo
MahdeTo

Reputation: 11194

You don't need it, the method performs the synchronization for you.

Upvotes: 1

Shivan Dragon
Shivan Dragon

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

Related Questions