[concurrency-interest] Thread-safety of hasMoreElements() of Vector

Praveen Kumar Jha javapk at gmail.com
Tue Jul 24 23:57:18 EDT 2012


Hi Mike,

Thanks for your response, now it makes sense for me. I suppose
you meant

synchronized('vector')  [not synchronized(enumer)]

in the example you cited.


Regards,
Praveen


On Tue, Jul 24, 2012 at 11:44 PM, Mike Duigou <mike.duigou at oracle.com>wrote:

>
> On Jul 24 2012, at 08:19 , Praveen Kumar Jha wrote:
> >>
> >
> >>
> >> If the backing vector is changing on some other thread then Enumeration
> is
> >> not a suitable API.  (This is probably the logic applied by the
> implementer
> >> who decided not to bother sync'ing hasMoreElements.)
> >
> >
> > But if that is the case then why is 'Vector.this' synchronized in
> > nextElement() method?
>
> To avoid accidentally generating a ArrayIndexOutOfBoundsException if the
> Vector shrinks or (just as bad) returning an element from the array that is
> not part of the Vector.
>
> > As I understand, the behavior of both hasMoreElements() and
> > nextElement() should be on the same lines as far as use of Enumeration
> > in multithreaded case is concerned.
>
> They could be but since the possibility of modification between
> hasMoreElements and nextElement exists making hasMoreElements synchronized
> on the vector wouldn't really solve anything. For true safety you would
> have to synchronize on the Vector outside of calls to
> hasMoreElements/nextElement. ie.
>
> Vector vector;
> Enumeration enumer = vector.elements();
> synchronized(enumer) {
>    while(enumer.hasMoreElements()) {
>      Object object = enumer.nextElement();
>      System.out.println(object);
>    }
> }
>
> Without the surrounding synchronized it is possible that this snippet will.
> - print all of the elements. (Yay!)
> - print something odd (duplicate elements, miss elements, etc.) based upon
> concurrent modification
> - fail with a NoSuchElementException if final element is concurrently
> removed after hasMoreElements() but before nextElement()
>
> > And, I am considering the case
> > when a thread is reading Vector using Enumeration while other thread
> > is mutating it.
>
> Probably a bad idea. Concurrent use of Vector should probably be limited
> to either non-structural modifications. ie. changes which don't change the
> size of the collection or very well ordered changes such as using Vector as
> a LIFO or FIFO (and there are better choices for this). If you are using
> Vector as a FIFO then perhaps just use removeElementAt(int index). Assuming
> only one thread is removing elements you aren't going to run into problems
> with atomicity in this usage.
>
> Mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120725/e01c795f/attachment.html>


More information about the Concurrency-interest mailing list