如果当前线程在Java中多次调用condition.await()会发生什么?



我想了解一下当我们执行下面的代码片段时到底发生了什么。

当线程执行someemethod()并命中while循环时,如果它一次又一次地调用await方法会发生什么?线程上下文是如何被Condition/ReentrantLock存储/维护的?

而且,一旦线程调用await(),就意味着它释放当前锁并进入等待状态。这是否意味着另一个线程可以获取该锁?如果是这样,在await()方法周围写一个while循环有什么用?

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
...
...
public void someMethod() {
lock.lock();
try {
for (int i = 2; i < n; i = i + 2) {
while (state != 2) {
condition.await();
}
printNumber.accept(i);
r.run();
state = 0;
condition.signalAll();
}
} finally {
lock.unlock();
}
}

如果我理解错了,请纠正我。提前谢谢。

等待循环的目的显然是等待状态为2。从等待调用中醒来仅仅意味着你已经被唤醒了。这并不意味着状态是2。

这个逻辑和我在半夜等着,看了看时钟,然后决定回去睡觉是一样的。: -)

请注意条件说明的文档明确指出可能发生虚假唤醒。这意味着任何条件的使用。不检查实际所需状态的Await几乎肯定有bug。

同时,这个代码似乎有缺陷。您知道,当线程在await中等待时,不会执行signalAll调用,对吧?因为线程在await中等待。需要有其他线程,执行不同的代码,可以发出条件信号,使这个线程从等待中解脱出来。


你的问题:

我想知道当我们执行下面的代码时到底发生了什么代码片段。

使用所示的代码,线程永远位于await调用中,因为没有显示可以唤醒它的代码。

(根据文档,存在虚假唤醒的可能性,如果发生这种情况,while循环将线程重新置于等待状态,因为正在等待的内容不会改变。)

关于"一次又一次调用await"——好吧,你不能在等待时调用await——因为当你不运行时,你没有地方调用任何东西。所以第一次和随后的呼叫没有区别。在每种情况下,调用线程都进入睡眠状态,直到条件随后被发出信号。

关于锁-锁在等待时被释放,并在唤醒时重新获得。这是实际需要;假设在你的例子中,锁保护了对'state'的访问,任何想要修改state和唤醒服务员的代码最好在锁的保护下进行。

相关内容

  • 没有找到相关文章