在了解了加锁和锁重入以后,最须要了解的仍是在分布式场景下或者多线程并发加锁是如何处理的?多线程
先来看结果,在多线程对 /locks/lock_01
加锁时,是在后面又建立了新的临时节点。并发
这块在加锁方法 CreateBuilderImpl#pathInForeground
中已经介绍过框架
这里判断 /locks/lock_01
路径已经存在,会直接建立新的临时顺序节点。分布式
真正判断锁是否获取成功,实际上是在 LockInternals#attemptLock
方法中的 internalLockLoop
方法中。oop
internalLockLoop
方法的主要做用是判断加锁结果,以及获取锁失败时,对其余节点的监听。ui
/locks/lock_01
下的全部子节点,按照从小到大排序,判断本身是否是获取到锁,没有获取到就监听本身前一个节点;是否获取锁的代码在 StandardLockInternalsDriver#getsTheLock
线程
这块就是判断是否为最小节点,由于在 getSortedChildren
中已经对全部节点排序,因此方法中的 List<String> children
是有序的。code
maxLeases
是在 InterProcessMutex
初始化的时候,指定的值为 1。blog
最终这里的结果是,判断本身是否是最小,不是最小,就将 pathToWatch 设置为前一个节点。排序
只监听本身的前一个节点,能够避免羊群效应!
为何要进行等待呢?
由于是为了防止无效自旋,由于这里有监听机制,会监听上一个节点是否释放。
这块是 ZooKeeper 的 Watcher 监听机制,在节点释放的时候,会进行回调,而后使用 Java 的 notifyAll 方法通知全部的 wait 线程。而后这里的 while trye 会继续执行,从新检查是否得到锁等。
本文主要介绍了基于 ZooKeeper 的分布式锁框架 Curator 在并发场景下的锁竞争问题。
重点须要了解的是: