我对这两个描述非常困惑:
以下是我的问题:
我知道Java中的每个对象都有一个锁,但“监视器锁”是什么意思?是否与oject的锁相同?
为什么通知方法需要放弃显示器锁?
如果我尝试使用以下代码使对象等待:
class simpleTask extends Thread
{
int waitingTime;
public simpleTask(int waitingTime)
{
this.waitingTime = waitingTime;
}
public void run()
{
synchronized(this) // this is a reference of current object
{
try {
this.wait(waitingTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
与上面的第一个描述一样,是指当前对象被synchronized关键字阻塞,然后wait方法释放锁?
答案 0 :(得分:7)
我知道Java中的每个对象都有一个锁,但“监视器锁”是什么意思?它与对象的锁相同吗?
是的,他们是一回事。它们偶尔也被称为对象的“互斥体”和对象的“原始锁定”。 (但是当有人谈到Lock
时,他们正在谈论this Java interface ...这是一个不同的锁定机制。)
为什么通知方法需要放弃显示器锁?
notify
方法不会放弃锁定。在notify
调用返回后,您的代码有责任放弃锁定(即保留同步块或从同步方法返回)。
为什么这有必要?因为当前正在等待该锁定的任何其他线程(在wait(...)
调用中)必须在wait
调用完成之前重新获取该锁定。
他们为什么这样设计notify
/ wait
?这样它们就可以用来实现条件变量。
与上面的第一个描述一样,是指当前对象被synchronized关键字阻塞,然后wait方法释放锁?
这是正确的。当一个线程调用someObject.wait()
时,someObject
上的锁被释放...然后在wait()
调用返回之前重新获取(由同一个线程)。当然,与此同时,其他线程已经多次获取并释放了锁someObject
。关键是当wait
返回时,调用wait
的线程将拥有锁。
答案 1 :(得分:0)
是的,显示器锁定与对象的锁定相同。如果你synchronized (object)
,那就是锁定。
在您的示例中,当前对象在等待时放弃锁定,wait()
调用放弃锁定。在另一个线程中,调用notify()
来唤醒对象,当wait()
调用返回时,它将再次保持锁定。
答案 2 :(得分:0)
A monitor is a type of synchronization construct.
等待放弃锁定的原因是其他线程可以获取锁定,例如可能要等待的其他线程。另外:通常在释放任何线程之前唤醒其他线程锁定的线程,以防止竞争条件。
有关此内容的更多信息,您应该研究条件变量(即condvars)。