privatebooleaninternalLockLoop(long startMillis, Long millisToWait, String ourPath) throws Exception
{
boolean haveTheLock = false;
boolean doDelete = false;
try
{
if ( revocable.get() != null )
{
client.getData().usingWatcher(revocableWatcher).forPath(ourPath);
}
while ( (client.getState() == CuratorFrameworkState.STARTED) && !haveTheLock )
{
// uuid - localname - sequence// ourPath :/path/uuid - localname - sequence//basePath : /path//return 回来为 按照sequence 进行排序
List<String> children = getSortedChildren();
//sequenceNodeName : uuid - localname - sequence
String sequenceNodeName = ourPath.substring(basePath.length() + 1); // +1 to include the slash//获取 getsTheLock:是否获取锁 pathToWatch:获取锁的 sequenceNode
PredicateResults predicateResults = driver.getsTheLock(client, children, sequenceNodeName, maxLeases);
if ( predicateResults.getsTheLock() )
{
haveTheLock = true;
}
else
{
// 获取锁的path
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// 如果该节点变化,则使用watch//notifyFromWatcher 唤醒所有的children,重新竞争
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 nodebreak;
}
wait(millisToWait); //睡眠相应的时间
}
else
{
//睡眠
wait();
}
}
catch ( KeeperException.NoNodeException e )
{
// it has been deleted (i.e. lock released). Try to acquire again
}
}
}
}
}
catch ( Exception e )
{
ThreadUtils.checkInterrupted(e);
doDelete = true;
throw e;
}
finally
{
//出现异常或者超时,删除此节点if ( doDelete )
{
deleteOurPath(ourPath);
}
}
return haveTheLock;
}
release
publicvoidrelease() throws Exception
{
/*
Note on concurrency: a given lockData instance
can be only acted on by a single thread so locking isn't necessary
*/
Thread currentThread = Thread.currentThread();
LockData lockData = threadData.get(currentThread);
if ( lockData == null )
{
thrownew IllegalMonitorStateException("You do not own the lock: " + basePath);
}
int newLockCount = lockData.lockCount.decrementAndGet(); //如果多次锁入,则需要多次释放if ( newLockCount > 0 )
{
return;
}
if ( newLockCount < 0 )
{
thrownew IllegalMonitorStateException("Lock count has gone negative for lock: " + basePath);
}
try
{
//为0时,释放 删除path节点就ok了
internals.releaseLock(lockData.lockPath);
}
finally
{
threadData.remove(currentThread);
}
}