A behavior mismatch in AbstractCollection.toArray(T[] )

David Holmes david.holmes at oracle.com
Tue Dec 13 11:55:29 UTC 2011

On 13/12/2011 8:16 PM, Ulf Zibis wrote:
> Am 13.12.2011 08:41, schrieb David Holmes:
>> Hi Sean,
>> On 13/12/2011 5:21 PM, Sean Chou wrote:
>>> When I was reading the code of AbstractCollection.toArray(T[] ), I
>>> found its behavior maybe different from the spec in multithread
>>> environment. The spec says "If the collection fits in the specified
>>> array, it is returned therein. Otherwise, a new array is allocated
>>> with the runtime type of the specified array and the size of this
>>> collection." However, in multithread environment, it is not easy to
>>> tell if the collection fits in the specified array, because the
>>> items may be removed when toArray is copying.
>> Right. The problem is that AbstractCollection doesn't address
>> thread-safety or any other concurrency issues so doesn't account for
>> the collection growing or shrinking while the toArray snapshot is
>> being taken. Really the collection implementations that are designed
>> to support multiple threads should override toArray to make it clear
>> how it should behave. As it stands, in my opinion, it is more a
>> "quality of implementation" issue as to whether AbstractCollection
>> expends effort after creating the array to see if the array is
>> actually full or not; or whether after creating an array it turns out
>> it could have fit in the original.
>> For a concurrent collection I would write the spec for toArray
>> something like:
>> "The current size of the collection is examined and if the collection
>> fits in the specified array it will be the target array, else a new
>> array is allocated based on that current size
> + with the runtime type of the specified array

Of course.

>> and it becomes the target array. If the collection grows such that the
>> target array no longer fits then extra elements will not be copied
>> into the target array. If the collection shrinks then the target array
>> will contain null elements."
> What about, if the size is not changed, but some elements were changed
> (could cause position change) or the order with same elements would be
> changed? This could cause inconsistencies and/or duplicates in the
> resulting array from a collection which in worst case doesn't allow
> duplicates, e.g. Set.
> IMHO, in concurrent collection, changing the collection's content should
> be blocked in consistent state until toArray is finished.

It's up to each concurrent collection to specify exactly what it means 
for itself. A concurrent Set may indeed have to do additional work if it 
wants to guarantee the array has no duplicates.


> -Ulf

More information about the core-libs-dev mailing list