Search code examples
javaconcurrencylinked-listsynchronizedproducer-consumer

Java Producer/Consumer Concurrency Issue - NoSuchElementFound Exception while trying to read objects


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;
    }
}

Solution

  • 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.