假设我有两个主题。 Thread1正在访问同步方法,同时,Thread2正在访问同一对象的另一个同步方法。据我所知,Thread2应该等到Thread1完成它的任务。我的问题是,对象的等待线程列表上是否有Thread2?对我来说似乎是这样,但是Thread2不会调用wait()方法,然后作为逻辑结果,它不应该在对象的等待线程列表上。如果它不在对象的等待线程列表中,那么Thread2的状态是什么?
答案 0 :(得分:2)
当Tread2等待Thread1释放Thread1持有的内部锁时,其阻塞直到内部锁变为可用(如执行线程Thread1释放的那样)。因此,在夏天,Thread2正在等待释放锁,因此它可以获取它。
现在,当线程调用wait()
时,它必须已经拥有内部锁。调用wait()
然后释放锁,并将线程置于等待状态,等待来自notify()
或notifyAll()
的信号继续执行。
因此,这两种情况是不同的,前者是关于执行隐式被阻止,直到资源(锁)变得可用。虽然后者是关于明确释放已经保持的锁定,然后等待其重新获取锁定并继续的信号。
答案 1 :(得分:0)
这两种情况之间存在差异,因为您需要注意。
当一个线程试图运行一个synchronized
块,但某个其他线程保持监视器的锁定时,传入的线程阻塞,直到锁被释放并被授予它。
对于要调用wait()
的线程,它必须已保持监视器的锁定(这是一个相关的区别)。
此外,调用wait()
会使线程等待(释放锁定),通常是由某个其他线程通知。
上面的通常 总是,在理想情况下,但是,正如Java文档中所指出的,一种称为虚假唤醒的现象可能会发生,等待线程唤醒没有明显的原因。这就是为什么等待条件应该包含在while
语句中,而不是if
。例如:
synchronized (this) {
while (x < 0) { wait(); }
}
而不是:
synchronized (this) {
if (x < 0) { wait(); }
}