如果我们在 Java 中的当前线程多次调用 condition.await() 会发生什么
What happens if we call condition.await() multiple times by the current thread in Java
我想了解当我们执行以下代码片段时到底发生了什么。
当线程执行 someMethod() 并进入 while 循环时,如果它一次又一次地调用 await 方法会发生什么?
Condition/ReentrantLock的线程上下文stored/maintained如何?
另外,线程一旦调用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。从 await 调用中醒来就意味着您已经醒来。不代表状态是2.
这个逻辑和我半夜起床,看看时钟,决定回去睡觉是一样的。 :-)
请注意 documentation for Condition 明确指出可能会发生虚假唤醒。这意味着任何不检查实际所需状态的 Condition.await 的使用几乎肯定有错误。
同时这段代码似乎有缺陷。您知道您不会在线程等待 await
时执行 signalAll
调用,对吗?因为线程正在等待await
。需要有一些其他线程,执行不同的代码,可以发出条件信号,以使该线程脱离等待状态。
您的问题:
I would like to understand what really happens when we execute the following
code snippet.
根据显示的代码,线程永远处于 await
调用中,因为没有显示可以唤醒它的代码。
(根据文档,存在虚假唤醒的可能性,如果发生这种情况,while 循环会将线程重新置于等待状态,因为正在等待的内容不会改变。)
关于 'calling await again and again' - 好吧,你不能在等待时调用 await - 因为当你不在 运行 时,你无处调用任何东西。因此,第一次调用和后续调用之间没有区别。在每种情况下,调用线程都会进入休眠状态,直到随后发出信号为止。
关于锁定 - 锁定在等待时释放,并在唤醒时重新获取。这是实际需要;大概在你的例子中,锁正在保护对 'state' 的访问,任何想要修改状态和唤醒服务员的代码最好在锁的保护下这样做。
我想了解当我们执行以下代码片段时到底发生了什么。
当线程执行 someMethod() 并进入 while 循环时,如果它一次又一次地调用 await 方法会发生什么? Condition/ReentrantLock的线程上下文stored/maintained如何?
另外,线程一旦调用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。从 await 调用中醒来就意味着您已经醒来。不代表状态是2.
这个逻辑和我半夜起床,看看时钟,决定回去睡觉是一样的。 :-)
请注意 documentation for Condition 明确指出可能会发生虚假唤醒。这意味着任何不检查实际所需状态的 Condition.await 的使用几乎肯定有错误。
同时这段代码似乎有缺陷。您知道您不会在线程等待 await
时执行 signalAll
调用,对吗?因为线程正在等待await
。需要有一些其他线程,执行不同的代码,可以发出条件信号,以使该线程脱离等待状态。
您的问题:
I would like to understand what really happens when we execute the following code snippet.
根据显示的代码,线程永远处于 await
调用中,因为没有显示可以唤醒它的代码。
(根据文档,存在虚假唤醒的可能性,如果发生这种情况,while 循环会将线程重新置于等待状态,因为正在等待的内容不会改变。)
关于 'calling await again and again' - 好吧,你不能在等待时调用 await - 因为当你不在 运行 时,你无处调用任何东西。因此,第一次调用和后续调用之间没有区别。在每种情况下,调用线程都会进入休眠状态,直到随后发出信号为止。
关于锁定 - 锁定在等待时释放,并在唤醒时重新获取。这是实际需要;大概在你的例子中,锁正在保护对 'state' 的访问,任何想要修改状态和唤醒服务员的代码最好在锁的保护下这样做。