假设我有两个线程。Thread1 正在访问一个同步方法,同时 Thread2 正在访问同一对象的另一个同步方法。据我所知,Thread2 应该等到 Thread1 完成它的任务。我的问题是,Thread2 在对象的等待线程列表中吗?对我来说似乎是这样,但是 Thread2 没有调用 wait() 方法,那么作为逻辑结果,它不应该在对象的等待线程列表中。如果它不在对象的等待线程列表中,那么 Thread2 的状态是什么?
问问题
114 次
2 回答
2
当 Tread2 等待 Thread1 释放 Thread1 持有的内在锁时,它会被阻塞,直到内在锁变得可用(如 u 被执行线程 Thread1 释放)。所以,总而言之,Thread2 正在等待锁被释放,所以它可以获取它。
现在,当一个线程调用 时wait()
,它必须已经持有内部锁。调用wait()
then会释放 lock,并将线程置于等待状态,等待来自notify()
或 a的信号notifyAll()
以继续执行。
所以,这两种情况是不同的,前者是关于执行被隐式阻塞,直到资源(锁)变得可用。而后者是关于显式释放一个已经持有的锁,然后等待一个信号,表明它是时候重新获取锁并继续了。
于 2013-04-30T23:54:55.377 回答
0
正如您正确指出的那样,这两种情况之间存在区别。
当一个线程试图运行一个synchronized
块,但另一个线程持有监视器的锁时,传入的线程被阻塞,直到锁被释放并授予它。
对于要调用的线程wait()
,它必须已经持有监视器的锁(这是一个相关的区别)。此外,调用wait()
使线程等待(释放锁),通常直到它被其他线程通知。
在理想情况下,通常上述情况应该总是如此,但是,如 Java 文档中所述,可能会发生一种称为虚假唤醒的现象,使等待线程无缘无故地唤醒。这就是为什么等待条件应该包含在一个while
语句中,而不是一个if
. 例子:
synchronized (this) {
while (x < 0) { wait(); }
}
代替:
synchronized (this) {
if (x < 0) { wait(); }
}
于 2013-04-30T23:57:55.713 回答