假设我有两个线程。 线程1正在访问同步方法,同时,线程2正在访问同一对象的另一个同步方法。 据我所知,线程2应等待线程1完成其任务。 我的问题是,线程2是否在对象的等待线程列表中? 对我来说似乎是这样,但线程2没有调用wait()方法,那么作为逻辑结果,它不应该在对象的等待线程列表中。 如果它不在对象的等待线程列表中,那么线程2的状态是什么?
这两种情况之间有所区别,您注意到了这一点。
当线程尝试运行一个synchronized
块时,但是其他线程持有监视器的锁时,传入的线程会被阻塞,直到锁被释放并授予它。
要让线程调用wait()
,它必须已经持有监视器的锁(这是一个相关的区别)。此外,调用wait()
会使线程等待(释放锁),通常直到某个其他线程通知它。
通常上面应该是总是,在理想情况下是如此,但是正如Java文档中指定的那样,可能会发生称为虚假唤醒的现象,使等待线程因没有明显的原因而唤醒。这就是为什么等待条件应该包含在while
语句中而不是if
语句中的原因。例如:
synchronized (this) {
while (x < 0) { wait(); }
}
不要:
synchronized (this) {
if (x < 0) { wait(); }
}