views:

71

answers:

2

I'm running into mutex issues with my Queue class under load which I'm at a loss to figure out why they are happening.

objects = new ArrayList<Object>();
public synchronized int getSize(){
 return objects.size();
}

public synchronized Object dequeue(){
 if(getSize()==0){
  try {
   wait();
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 return objects.remove(0);
}

public synchronized void enqueue(Object o){
 objects.add(o);
 notify();
}

It seems as if the dequeue method after a while is causing Java.lang.IndexOutOfBoundsException which to me looks like threads have been able to call the dequeue method multiple times when it shouldnt be. Any ideas ???

W

+1  A: 

It is possible for wait() to return without another thread calling notify(), and that would explain the exception that you are seeing.

Try

while(getSize()==0)

and

notifyAll();

instead of

if(getSize()==0)

and

notify();
finnw
Cheers m8..As a brief follow up my unit tests are obv not advanced enough to pick this up. Any methodologies you can recomend - I've been meaning to look into groboutils as junit isnt really suited to multithreading tests.
wmitchell
@imerez - ask this as a new question.
Stephen C
A: 

When multiple threads are waiting in the dequeue method and wake up or get an InterruptedException (for a reason other than the notify) they will try to get an object off the queue even when it is empty.

If you change your method to be:

public synchronized Object dequeue(){
 while (getSize()==0){
  try {
   wait();
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 return objects.remove(0);
}

the problem should be gone, and as a bonus you can use notifyAll() instead of relying on the behaviour of notify.

rsp
It's probably not an `InterruptedException`. That would show up in the stack trace.
finnw