We have this implementation of producer consumer. Occassionally we get NoSuchElementException in the readRecord() method. Ideally this should not happen as there is an if statement, and the method is synchronzied which makes sure that only one thread gets executed at any point in time. But still we get NoSuchElementException. Can somebody please guide me one this?
import java.util.LinkedList;
public class Listner{
private LinkedList<Object> objList = new LinkedList<Object>();
private Object listLock = new Object();
public void writeRecord(Object obj){
synchronized(listLock) {
objList.add(obj);
}
}
public synchronized Object readRecord(){
Object obj = null;
if( !objList.isEmpty() )
obj = objList.removeFirst();
return obj;
}
}
Your readRecord
is synchronized, so there can be at most one readRecord
at a time, but there is nothing preventing a readRecord
and writeRecord
running concurrently because they are locking on different objects. If it so happens that writeRecord
is in the middle of adding a record so isEmpty
returns false, but removeFirst
cannot find the element because writeRecord
hasn't finished adding it, you'd get that exception.
Synchronize on listLock
in readRecord
, or get rid of listLock
and declare both methods as synchronized to fix it.