为什么我必须使用相同的对象来同步和调用 wait/notify,但使用 class 条件我可以使用各种?
Why I must use same object to synchronize and call wait/notify, but using class Condition I can use various?
我想从 IllegalMonitorStateException 开始,如果当前线程不是对象监视器的所有者,我们将得到该异常。所以如果我这样做,我会得到异常:
public class Testing {
Object objLock = new Object();
void dance(){
synchronized (this){
objLock.wait();
}
}
}
所以我得出结论,您必须有相同的对象才能同步和调用 wait/notify。这是否意味着我每个锁只能有一个条件?
但是还有Condition class和Lock接口。他们是如何解决这个问题的?
public class Testing {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void dance(){
lock.lock();
condition.await();
lock.unlock();
}
}
之前我学错了,这是否意味着Lock/Condition例子让我们有更多的条件?当我刚刚展示 IllegalMonitorStateException 的示例时,为什么会阻止我们这样做。
有人可以解释我的困惑吗? Condition class 'trick it' 是怎么做到的?还是做了,如果我说错了?
首先让我们看看official documentation of Conditions:
Condition factors out the Object monitor methods (wait, notify and
notifyAll) into distinct objects to give the effect of having multiple
wait-sets per object, by combining them with the use of arbitrary Lock
implementations. Where a Lock replaces the use of synchronized methods
and statements, a Condition replaces the use of the Object monitor
methods.
并且根据official doc of Lock:
Lock implementations provide more extensive locking operations than
can be obtained using synchronized methods and statements. They allow
more flexible structuring, may have quite different properties, and
may support multiple associated Condition objects.
因此,我将使用这些信息来回答您的问题:
does this mean that Lock/Condition example allows us to have more conditions?
是的,每个锁可以使用多个条件,并使用条件组合创建同步逻辑。请参阅官方文档中的示例。
你得到 IllegalMonitorStateException
的原因是你试图在没有监视器的情况下等待对象(你应该传递 objLock
作为同步块参数)。你没有通过第二个代码示例得到它的原因是你没有在没有监视器的情况下对对象执行非法等待操作。您通过调用 lock.lock()
锁定资源,并在满足某些条件后解锁它们。在此之前,没有其他线程可以访问这些资源。显然,这背后没有任何魔法或诡计。
P.S.: 我建议您阅读有关 Lock
和 Condition
的文档,因为我发现它们在您遇到问题时非常有用且内容丰富。
我想从 IllegalMonitorStateException 开始,如果当前线程不是对象监视器的所有者,我们将得到该异常。所以如果我这样做,我会得到异常:
public class Testing {
Object objLock = new Object();
void dance(){
synchronized (this){
objLock.wait();
}
}
}
所以我得出结论,您必须有相同的对象才能同步和调用 wait/notify。这是否意味着我每个锁只能有一个条件?
但是还有Condition class和Lock接口。他们是如何解决这个问题的?
public class Testing {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void dance(){
lock.lock();
condition.await();
lock.unlock();
}
}
之前我学错了,这是否意味着Lock/Condition例子让我们有更多的条件?当我刚刚展示 IllegalMonitorStateException 的示例时,为什么会阻止我们这样做。 有人可以解释我的困惑吗? Condition class 'trick it' 是怎么做到的?还是做了,如果我说错了?
首先让我们看看official documentation of Conditions:
Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.
并且根据official doc of Lock:
Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, and may support multiple associated Condition objects.
因此,我将使用这些信息来回答您的问题:
does this mean that Lock/Condition example allows us to have more conditions?
是的,每个锁可以使用多个条件,并使用条件组合创建同步逻辑。请参阅官方文档中的示例。
你得到 IllegalMonitorStateException
的原因是你试图在没有监视器的情况下等待对象(你应该传递 objLock
作为同步块参数)。你没有通过第二个代码示例得到它的原因是你没有在没有监视器的情况下对对象执行非法等待操作。您通过调用 lock.lock()
锁定资源,并在满足某些条件后解锁它们。在此之前,没有其他线程可以访问这些资源。显然,这背后没有任何魔法或诡计。
P.S.: 我建议您阅读有关 Lock
和 Condition
的文档,因为我发现它们在您遇到问题时非常有用且内容丰富。