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

Gregg Wonderly gregg at cytetech.com
Thu Jul 19 12:58:55 EDT 2012


On 7/19/2012 11:40 AM, Yuval Shavit wrote:
> It seems like it's more problematic than that. Vector.elementCount isn't
> volatile, so if you create an Enumeration (and keep it thread-local), but the
> backing Vector changes on some other thread, hasMoreElements() is broken. I
> think that method needs to be synchronized on Vector.this.

If you do

while (true) {
	boolean more;
	synchronized(vector) {
		more = vector.hasMoreElements();
	}
	if( !more) break;

	...

}

Then you can "synchronize" with the state of other threads, obviously.  But it 
definitely looks like it's broken for that use case.  One could argue, that it 
would not be very productive for two threads to use an instance in this mode, 
without some other "happens-before" going on anyway.  For example, if you have a 
thread adding elements and another processing them, there should be a semaphore 
of some sort.  I would really be surprised to find code that used an instance 
without some other happens-before relationship between the two threads, which 
would cause the value to be correct.

Gregg

> On Thu, Jul 19, 2012 at 12:11 PM, Joe Bowbeer <joe.bowbeer at gmail.com
> <mailto:joe.bowbeer at gmail.com>> wrote:
>
>     The Enumeration API is not suitable for multi-threaded use because there is
>     a window for change between the hasMoreElements call and the subsequent
>     nextElement call.
>
>     In almost all cases the Enumeration is consumed in the same thread in which
>     it is produced.
>
>     The strange corner case that you envision is: one thread creates an
>     Enumeration and hands it to another thread.  The other thread calls
>     hasNextElement and may see a stale value for elementCount, causing it to end
>     too early (not calling nextElement) or to fail unexpectedly when it does
>     call nextElement.
>
>     With this scenario in mind, using "synchronized" in hasMoreElements is more
>     correct, though in practice I doubt it will make any difference.
>
>     Joe
>
>     On Thu, Jul 19, 2012 at 8:12 AM, Praveen Kumar Jha wrote:
>
>         Hello,
>
>         Please help me in understanding the thread-safety of hasMoreElements()
>         of Vector from visibility point of view. The hasMoreElements()
>         accesses the 'elementCount' field without synchronizing over
>         'Vector.this', like it is done in nextElement() method.
>
>         public Enumeration<E> elements() {
>              return new Enumeration<E>() {
>                  int count = 0;
>
>                  public boolean hasMoreElements() {
>                  return count < elementCount;
>                  }
>
>                  public E nextElement() {
>                  synchronized (Vector.this) {
>                      if (count < elementCount) {
>                      return (E)elementData[count++];
>                      }
>                  }
>                  throw new NoSuchElementException("Vector Enumeration");
>                  }
>              };
>              }
>
>         This might cause a thread to see stale value of 'elementCount' and thus
>         hasMoreElements() might incorrectly return true or false.
>         Javadoc of neither Enumeration nor elements() of Vector says anything
>         about thread-safety.
>
>         Regards,
>         Praveen
>
>
>     _______________________________________________
>     Concurrency-interest mailing list
>     Concurrency-interest at cs.oswego.edu <mailto:Concurrency-interest at cs.oswego.edu>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>



More information about the Concurrency-interest mailing list