我正在阅读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
}
}
}
}
我从Object
读取了javadoc,并且应该始终检查循环中的条件,如下所示:
synchronized (obj) {
while (condition does not hold&)
obj.wait(timeout);
... // Perform action appropriate to condition
}
哪个代码是对的?
更新
Here是Curator
的源代码。
因为haveTheLock
是一个局部变量,所以没有其他线程会改变它,所以代码工作正常。
答案 0 :(得分:0)
同步块在
中是。它有两个分支:
wait()
:无条件检查wait(millisToWait)
,每次循环时重新计算等待毫秒数所以虚假的唤醒不会产生任何影响。在javadoc中将while循环置于内同步块的主要原因是,通常需要同步以确保条件的结果可见。
在您显示的代码中,我的意思是client.getState()
和haveTheLock
都应该是线程安全的(例如volatile变量)。