【问题标题】:IllegalMonitorStateException occurs even when the thread holds the ReentrantLock object即使线程持有 ReentrantLock 对象,也会发生 IllegalMonitorStateException
【发布时间】:2021-04-22 01:16:13
【问题描述】:

即使锁被写入器线程持有,当运行下面提到的代码时,也会发生以下异常。

作家已进入临界区!信息:在痛苦中保持坚强 锁住了! java.lang.Object.notifyAll 处的线程“Writer”java.lang.IllegalMonitorStateException 中的异常(本机方法)

public class Buffer {
    private StringBuilder text;
    private final int MAX_PERMITS;
    private ReentrantLock writerLock = new ReentrantLock();
    private Semaphore semaphore;

    public Buffer(int maxPermits) {
        text = new StringBuilder();
        MAX_PERMITS = maxPermits;
        semaphore = new Semaphore(MAX_PERMITS);
    }

    public void write(String message) throws InterruptedException {
        writerLock.lock();
        System.out.println(ANSI_BLUE + Thread.currentThread().getName() + " has entered the critical section! Message: " + message);
        text.append(message); text.append(". ");
        Thread.sleep(2000);

        if(writerLock.isHeldByCurrentThread()) {
            System.out.println(ANSI_BLUE+"Lock held!");
            writerLock.notifyAll();
        }
        writerLock.unlock();
    }
    public void read() throws InterruptedException{
        if(text.length()==0) return;
        writerLock.lock();
        semaphore.acquire();
        System.out.println(ANSI_GREEN+Thread.currentThread().getName()+" read the following message: "+text.toString());
        semaphore.release();
        writerLock.unlock();
    }
}

【问题讨论】:

    标签: illegalstateexception


    【解决方案1】:

    ReentrantLock 等显式锁本质上是一种独立于隐式“同步”锁的锁定类型。换句话说,锁定/解锁 ReentrantLock 是一个独立于同步/等待/通知方案的方案。所以你需要决定你要使用哪种方案:

    • 使用显式锁,您需要在锁上创建条件(请参阅 Lock.newCondition() 方法),然后在条件上使用 signal() 和 await()。
    • 使用隐式锁,在调用 wait()/notify() 之前,您需要在相关对象上进行同步以获取锁

    您的代码的问题本质上是您试图在两种方案之间“混合和匹配”。

    显式条件的优点是您可以创建不同的条件,因此可以在代码中明确说明您发出信号/等待的实际原因(条件)是什么。您还可以决定锁是否“公平”。

    隐式同步锁的缺点包括:

    • 每个对象只有一个,因此在您的代码中可能不太清楚为什么您实际上在等待/通知;
    • 同步锁本质上是“先进先出”,因此占用锁的线程可能会在很长一段时间内使其他线程无法获得它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-27
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多