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.
David
-Ulf