Zookeeper分布式锁实现Curator十一问(四)

pivoteic
发布于 2022-6-15 17:06
浏览
0收藏

 

当前一个节点被删除了,也就是释放了锁,那么就会回调这个监听器watcher的方法。

Zookeeper分布式锁实现Curator十一问(四)-鸿蒙开发者社区Zookeeper分布式锁实现Curator十一问(四)-鸿蒙开发者社区

所以,这个watcher的作用就是调用notifyAll方法唤醒调用wait方法的线程,这样线程就会继续尝试加锁,因为是在一个while的循环中。

 

六、如何实现阻塞等待一定时间还未加锁成功就放弃加锁

 

可通过下面这个方法来实现实现阻塞等待一定时间还未加锁成功就放弃加锁。

boolean acquire(long time, TimeUnit unit) throws Exception

这个方法相比不指定等待时间的方法最主要的区别就是加锁失败之后,调用的阻塞的方法不一样。当不指定超时时间就会调用wait()方法,不会传入等待时间,不被唤醒就会一直阻塞;指定超时时间的时候,就会调用wait(long timeout)指定等待的时间,这样如果等待时间一到,线程就会醒过来,然后再次尝试加锁,一旦加锁失败,就会放弃加锁。

Zookeeper分布式锁实现Curator十一问(四)-鸿蒙开发者社区

七、如何主动释放锁和避免其它线程释放锁

 

释放锁release方法

Zookeeper分布式锁实现Curator十一问(四)-鸿蒙开发者社区

释放锁其实很简单,就是拿出当前线程对应的LockData,如果没有,就说明当前线程没有加过锁,就会抛出异常,所以Curator就是通过这个判断来防止其它线程释放了自己线程加的锁。

 

如果加锁了,那么LockData就不会为null,然后将加锁次数递减1,得到newLockCount,代表了剩下的加锁次数。

 

  • 如果newLockCount > 0,说明锁没释放完,有可重入加锁,然后什么事都不干,直接返回了。
  • 如果newLockCount < 0,就抛异常,但是一般不会出现。
  • 剩下的一种情况就是newLockCount == 0 ,说明锁已经完完全全释放完了,然后通过internals.releaseLock删除加锁的节点。

 

服务端删除节点之后,就会通知监听该节点的客户端,然后客户端就会回调watcher监听器,唤醒阻塞等待的线程,线程被唤醒后再进行一次判断就能加锁成功。

 

到这里,就讲完了加锁和释放锁的过程,整个加锁和释放锁的过程就如下图所示。

Zookeeper分布式锁实现Curator十一问(四)-鸿蒙开发者社区

文章转自公众号:三友的java日记

标签
已于2022-6-15 17:06:58修改
收藏
回复
举报
回复
    相关推荐