如何解决为什么我必须使用同一对象进行同步并调用等待/通知,但是使用类Condition可以使用各种对象?
我想从IllegalMonitorStateException开始,如果当前线程不是对象监视器的所有者,我们将得到IllegalMonitorStateException。因此,如果我这样做,我将得到异常:
public class Testing {
Object objLock = new Object();
void dance(){
synchronized (this){
objLock.wait();
}
}
}
所以我得出结论,您必须具有相同的对象才能进行同步并调用等待/通知。那是否意味着每个锁只能有一个条件?
但是接着有Condition类和Lock接口。他们如何设法解决工作?
public class Testing {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void dance(){
lock.lock();
condition.await();
lock.unlock();
}
}
在我学到错误之前,这是否意味着“锁定/条件”示例允许我们拥有更多条件?以及当我仅显示IllegalMonitorStateException的示例如何阻止我们执行此操作时,结果如何。 有人可以解释我的困惑吗? Condition类如何“欺骗”它?还是我说错了?
解决方法
首先,让我们看看official documentation of Conditions:
条件排除了对象监视器方法(等待,通知和 notifyAll)分成不同的对象以产生具有多个效果 每个对象的等待集,通过使用任意锁定将它们组合在一起 实现。锁代替同步方法的地方 和语句,条件替换了对象监视器的使用 方法。
锁实现提供比锁更广泛的锁操作 可以使用同步方法和语句获得。他们允许 更灵活的结构,可能具有完全不同的属性,并且 可能支持多个关联的Condition对象。
因此,使用这些信息,我将回答您的问题:
这是否意味着“锁定/条件”示例允许我们拥有更多条件?
是的,每个锁可以使用多个条件,并使用条件的组合来创建同步逻辑。参见官方文档中的示例。
您得到IllegalMonitorStateException
的原因是您试图等待对象而没有监视器(您应该已经将objLock
作为同步块参数传递了)。您没有在第二个代码示例中得到它的原因是,您在没有监视对象的情况下不会对对象执行非法的等待操作。您可以通过调用lock.lock()
来锁定资源,并在满足某些条件后将其解锁。在此之前,没有其他线程可以访问这些资源。显然,背后没有魔术或诡计。
P.S .:我建议您阅读Lock
和Condition
上的文档,因为我发现它们对您的问题非常有用且很有帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。