gpt4 book ai didi

Java ReentrantLock.unlock/await()/signal() 不抛出 IllegalMonitorStateException

转载 作者:行者123 更新时间:2023-12-02 05:44:45 25 4
gpt4 key购买 nike

我哪里出错了?即使我的消费者线程没有持有锁,程序也不会为任何锁调用(解锁/等待/信号)抛出 IllegalMonitorStateException。

更新:

private final ReentrantLock lock = new ReentrantLock();
private final Condition producers = lock.newCondition();
private final Condition consumers = lock.newCondition();

@Override
public void run() {

while (true) {
try {
//lock.lockInterruptibly();
try {
while (sharedResource.isEmpty()) {
printErr(name + " : Queue Empty ..");
consumers.await(500, TimeUnit.MILLISECONDS);
}

String obj = sharedResource.remove(0);
printOut(name + " : " + obj);
if (obj.equals(POISON_PILL)) {
sharedResource.add(POISON_PILL);
// System.err.println(name +" Taking break");
break;
}

producers.signal();
} finally {
lock.unlock();
}
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}

// if(debug)System.err.println("Consumer Looping");
}
}

void java.util.concurrent.locks.ReentrantLock.unlock()

根据 Java Doc 。公共(public)无效解锁()尝试释放此锁。如果当前线程是该锁的持有者,则持有计数会递减。如果现在保持计数为零,则释放锁定。 如果当前线程不是该锁的持有者,则抛出 IllegalMonitorStateException

最佳答案

这个问题似乎是基于一些不正确的假设/陈述。

  1. Java ReentrantLock 类没有 awaitsignal 方法。

  2. 这意味着 consumers (很可能)不是 ReentrantLock ...并且您的代码片段中没有任何内容调用 signal (或信号(原文如此))。

  3. 根据 javadoc,ReentrantLock 锁定和解锁方法不会抛出 IllegalMonitorStateException。我不希望它们这样做,因为锁定和解锁方法不作为原始监视器/互斥体运行。

据我所知,从 Lock 对象中获取异常的唯一方法是使用原始互斥操作 waitnotify 。 ..这似乎是对 Lock 对象的不当使用。 (如果您想使用这些操作,任何对象就足够了,包括一个普通的Object实例。)

Lock 类旨在提供与 Java 原始锁正交的锁定,并且不限于严格的 block 结构。他们不直接提供await 和signal。如果你想要这样,你需要创建一个条件;例如使用Lock.newCondition()。请注意,如果当前线程没有持有 Lock,Condition.await 和 signal 方法通常会抛出 IllegalMonitorStateException ...但是这种行为是具体实现的;请参阅javadoc .

<小时/>

因此,假设consumers是一个Condition,那么有几个原因可能导致它不会抛出异常:

  1. 它可能不是由 lock 表示的 Lock 的条件。

  2. 实际的Lock类可能提供不需要持有锁的Condition对象...

不幸的是,您的代码片段缺少一些可以解决这些问题的重要线索。

<小时/>

更新

我将您的代码转换为我可以运行的代码:

package test;

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

public class Lochy {

public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition producers = lock.newCondition();
Condition consumers = lock.newCondition();

while (true) {
try {
try {
for (int i = 0; i < 3; i++) {
System.out.println("wait " + i);
consumers.await(500, TimeUnit.MILLISECONDS);
}
producers.signal();
} finally {
lock.unlock();
}
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

当我运行该程序时,我在 unlock 处看到一个 IllegalMonitorStateException

当我注释掉 unlock() 时,我在 await 处看到 IllegalMonitorStateException

事后看来,发生的事情很清楚。在这两种情况下,await 都会引发 IllegalMonitorStateException,但是当您在 finally block 中调用 unlock() 时,抛出另一个 IllegalMonitorStateException ...所以你看不到第一个。

简而言之,这些方法的行为完全符合规范所述。

关于Java ReentrantLock.unlock/await()/signal() 不抛出 IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24197744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com