A behavior mismatch in AbstractCollection.toArray(T )
Ulf.Zibis at gmx.de
Tue Dec 13 10:16:01 UTC 2011
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
> 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.
More information about the core-libs-dev