使用 ReentrantLock 时出现 java.lang.IllegalMonitorStateException 错误?

标签 java multithreading java.util.concurrent

我正在尝试使用 ReentrantLock 实现阻塞 FIFO。除了抛出 IllegalMonitorStateException 外,一切正常。 当我们尝试释放未被线程锁定的资源时,可能会发生此错误。但是我找不到为什么会出现此错误。

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

}

异常

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)

最佳答案

不要使用

tryLock()

但是

lock()

因为tryLock()会返回一个boolean值,这意味着如果可能它会尝试加锁,但是如果锁已经被另一个线程加锁,它会立即返回false。

然后当你想在finally中解锁时,由于锁没有被当前线程持有,会抛出IllegalMonitorStateException。

关于使用 ReentrantLock 时出现 java.lang.IllegalMonitorStateException 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40275653/

相关文章:

c++ - std::condition_variable – 通知一次但等待线程被唤醒两次

c# - 如何在不循环的情况下等待 bool 值(使用任何类型的等待/信号量/事件/互斥量等)

java - 线程中的 sleep 和连接输出

java - 按需执行线程数有限的执行器

java - 使用Gson转换为JSON格式的问题

java - 如何制作一个像回收站一样的Android应用程序?

Java 正则表达式 - 如何应用正则表达式来获取所有由 ASCII 字符括起来的字符串?

c# - 在asp.net和java之间共享 session 变量

java - Lambda 表达式没有有效的 final 变量

java - 为什么ExecutorService方法invokeAny()在每次运行的程序上都处理不同数量的任务?