我很难真正理解,这是如何运作的:
while(<some condition>){
wait();
}
OR this example:
while(<some condition>){
condition.await();
}
当线程已经通过<some condition>
时,
它可能真的发生了,<some condition>
执行false
或wait()
时await()
已经wait()
。
因此,await()
或function playToFive() {
console.log('Let\'s play Rock Paper Scissors');
var playerWins = 0;
var computerWins = 0;
while (playerWins === 5 || computerWins === 5) {
if (humanVsMachine === 'player') {
playerWins += 1;
} else if (humanVsMachine === 'computer') {
computerWins += 1;
}
return [playerWins, computerWins];
}
}
console.log(playToFive());
可能会因已经无效的条件而被调用 - 这意味着意图被打破。
我的逻辑出了什么问题?
答案 0 :(得分:2)
从Object#wait()
或Condition#await()
唤醒意味着重新获取相关锁定。 据推测,只有在拥有锁时才能修改<some condition>
。因此,如果现在醒来的线程拥有锁,则其他任何线程都不能将条件更改为false。
答案 1 :(得分:2)
来自wait()
的{{3}}:
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法通知等待此对象监视器上的线程唤醒notifyAll方法。然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
(强调我的)
换句话说,如果没有synchronized
块,您的代码将抛出IllegalMonitorStateException
。另一方面, synchronized
,您的状况将通过wait();
电话原子检查。
这并不意味着你没有任何问题,因为这里的“原子”只是关于你正在同步的对象(在你的情况下是this
),而只是相对于其他同步访问宾语。如果您的条件取决于不同的对象,或者您在其他地方没有同步的情况下访问该对象,则事情可能会变坏。因此,不要这样做。
使用Lock
和Condition
s的原因相同。 docs条件变量派生自锁定对象,synchronized
/ wait
/ notify
类似于lock
; unlock
/ {{1} } / await
。