[英]What's the right way to deal with spurious wakeup?
I am reading Curator
's source code, and found some code below: 我正在阅读Curator
的源代码,并在下面找到了一些代码:
while ( (client.getState() == CuratorFrameworkState.STARTED) && !haveTheLock )
{
List<String> children = getSortedChildren();
String sequenceNodeName = ourPath.substring(basePath.length() + 1); // +1 to include the slash
PredicateResults predicateResults = driver.getsTheLock(client, children, sequenceNodeName, maxLeases);
if ( predicateResults.getsTheLock() )
{
haveTheLock = true;
}
else
{
String previousSequencePath = basePath + "/" + predicateResults.getPathToWatch();
synchronized(this)
{
try
{
// use getData() instead of exists() to avoid leaving unneeded watchers which is a type of resource leak
client.getData().usingWatcher(watcher).forPath(previousSequencePath);
if ( millisToWait != null )
{
millisToWait -= (System.currentTimeMillis() - startMillis);
startMillis = System.currentTimeMillis();
if ( millisToWait <= 0 )
{
doDelete = true; // timed out - delete our node
break;
}
wait(millisToWait);
}
else
{
wait();
}
}
catch ( KeeperException.NoNodeException e )
{
// it has been deleted (i.e. lock released). Try to acquire again
}
}
}
}
I read javadoc from Object
and should always check condition in loops, like this : 我从Object
读取Javadoc,并且应始终检查循环中的条件,如下所示:
synchronized (obj) {
while (condition does not hold&)
obj.wait(timeout);
... // Perform action appropriate to condition
}
which code is right? 哪个代码正确?
Update 更新资料
Here is the source code of Curator
. 这是Curator
的源代码。
Because haveTheLock
is a local variable, no other thread would change it, so the code works fine. 因为haveTheLock
是一个局部变量,所以没有其他线程可以更改它,因此代码可以正常工作。
The synchronized block is within a while loop. 同步块是一个while循环内。
And it has two branches: 它有两个分支:
wait()
: no condition to check 无限的wait()
:无条件检查 wait(millisToWait)
and the amount of millis to wait is recalculated at each loop 一个定时的wait(millisToWait)
和wait(millisToWait)
数在每个循环中重新计算 So spurious wakeups won't really have an effect. 因此,虚假唤醒不会真正起作用。 The main reason to have the while loop inside the synchronized block as in the javadoc is that very often you need the synchronization to make sure the result of the condition is visible. 像Javadoc一样,在同步块内使用while循环的主要原因是,经常需要进行同步以确保条件的结果可见。
In the code you show, I means that both client.getState()
and haveTheLock
should be thread safe (for example volatile variables). 在您显示的代码中,我的意思是client.getState()
和haveTheLock
都应该是线程安全的(例如,volatile变量)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.