Datta
Datta

Reputation: 87

java.lang.IllegalMonitorStateException error while using ReentrantLock?

I'm trying to implement blocking FIFO using ReentrantLock. Everything works fine except it is throwing IllegalMonitorStateException. When we try to release a resource that is not locked by the thread this error might occur. But I couldn't find why this error coming here.

package edu.utdallas.blockingFIFO;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import edu.utdallas.taskExecutor.Task;

public class ArrayBlockingQueue implements BlockingFIFOque{
    private final Task[] arr;
    private int arrSize;
    private int start;
    private int end;
    private int ocupied;
    private final Lock mlock = new ReentrantLock();
    private Condition Empty = mlock.newCondition();
    private Condition Full = mlock.newCondition();

    public ArrayBlockingQueue(int Size) {

        arrSize = Size;
        start = 0;
        end = 0;
        ocupied = 0;
        arr = new Task[arrSize];
    } 

    @Override
    public void put(Task item) throws Exception {

        mlock.tryLock();
        try{
            while(ocupied == arrSize) Full.await();
            ocupied++;
            arr[end++]=item;
            if(end > arrSize-1){
                end = end - arrSize;
            }
            Empty.signalAll();
        } finally{
            mlock.unlock();
        }
    }


    @Override
    public Task take() throws Exception {

        Task item;
        mlock.tryLock();
        try{
            while(ocupied == 0) Empty.await();
            ocupied = ocupied - 1;
            item = arr[start];
            start++;
            if(start > arrSize-1){
                start = start - arrSize;
            }
            Full.signal();
        }finally{
            mlock.unlock(); //Error here only
        }

        return item;
    }

}

The exception

java.lang.IllegalMonitorStateException******  Adding Task SimpleTask141
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)
    at java.util.concurrent.locks.ReentrantLock.unlock(Unknown Source)
    at edu.utdallas.blockingFIFO.ArrayBlockingQueue.take(ArrayBlockingQueue.java:61)
    at edu.utdallas.taskExecutorImpl.TaskExecutorImpl$1.run(TaskExecutorImpl.java:38)

Upvotes: 1

Views: 1423

Answers (1)

T.Tony
T.Tony

Reputation: 515

Don't use

tryLock()

but

lock()

Because the tryLock() will return a boolean value, which means it will try to lock if possible, but if the lock has been locked by another thread, it will return false immediately.

Then when you want to unlock it in finally, as the lock was not held by the current thread, IllegalMonitorStateException will be thrown.

Upvotes: 3

Related Questions