Java ReentrantLock.unlock/await()/signal()未引发IllegalMonitorStateException
我哪里做错了?即使我的使用者线程没有持有锁,程序也不会对任何锁调用(unlock/await/signal)抛出非法监视器状态异常 更新:Java ReentrantLock.unlock/await()/signal()未引发IllegalMonitorStateException,java,multithreading,locking,Java,Multithreading,Locking,我哪里做错了?即使我的使用者线程没有持有锁,程序也不会对任何锁调用(unlock/await/signal)抛出非法监视器状态异常 更新: private final ReentrantLock lock = new ReentrantLock(); private final Condition producers = lock.newCondition(); private final Condition consumers = lock.newCondition(); @Override
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。
公开作废解锁()
试图释放此锁。
如果当前线程是此锁的保持器,则保持计数将减少。如果保持计数现在为零,则释放锁
如果当前线程不是此锁的持有者,则会抛出IllegalMonitorStateException
此问题似乎基于一些不正确的假设/陈述
ReentrantLock
类没有await
或signal
方法消费者
很可能不是可重入锁
。。。代码段中没有任何内容调用signal
(或singnal
(sic))ReentrantLock
lock和unlock方法不会抛出IllegalMonitorStateException
。我也不希望他们这样做,因为lock和unlock方法并没有像原始监视器/互斥体那样工作锁
对象中获取该异常的唯一方法是使用基本互斥操作等待
和通知
。。。这似乎是对Lock
对象的不当使用。(如果要使用这些操作,任何对象都可以,包括一个普通的对象
实例。)
Lock
类被设计为提供与Java基本锁正交的锁,并且不受严格块结构的限制。它们不直接提供等待和信号。如果需要,您需要创建一个条件
;e、 g.使用Lock.newCondition()
。请注意,如果当前线程未持有锁
,Condition.await和signal方法通常会抛出IllegalMonitorStateException
。。。但这种行为是具体实施的;看
因此,假设
消费者
是一个条件
,那么它可能不会引发异常的原因有两个:
Lock
表示的Lock
的条件锁
类可以提供不需要持有锁的条件
对象更新 我将您的代码转换为可以运行的代码:
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();
}
}
}
}
封装测试;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.locks.Condition;
导入java.util.concurrent.locks.ReentrantLock;
公共级洛希{
公共静态void main(字符串[]args){
ReentrantLock=新的ReentrantLock();
条件生产者=lock.newCondition();
条件使用者=lock.newCondition();
while(true){
试一试{
试一试{
对于(int i=0;i<3;i++){
System.out.println(“等待”+i);
消费者。等待(500,时间单位。毫秒);
}
生产者。信号();
}最后{
lock.unlock();
}
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}
当我运行它时,我在解锁
处看到一个非法监视器状态异常
当我注释掉unlock()
时,我在wait
中看到IllegalMonitorStateException
事后看来,很清楚发生了什么。在这两种情况下,await
都会引发IllegalMonitorStateException
,但当您在finally
块中调用unlock()
时,会引发另一个IllegalMonitorStateException
。。。所以你看不到第一个
简而言之,这些方法的行为完全符合规范的要求。这看起来像Java代码。为什么你也用c#标记它?为什么他们会抛出异常?更新了我的帖子。消费者和生产者是条件。根据java文档,如果当前线程没有持有锁,则调用unlock with throw IllegalMonitorStateException。