一、Redis分布式锁
1、线程调用setnx(lockkey,currentTime+timeout),设置成功,也就是返回true,给这个key设置有效期;
2、设置成功,调用expire(lockkey,timeout),设置锁的过期时间,执行业务,然后调用del(lockkey),释放锁。
3、设置失败,表示当前锁正在使用,则调用get(lockkey) 得到valueA;
4、如果valueA!=null && currentTime (当前时间毫秒数)>valueA,表示超时,执行5;
5、超时时,调用getset(lockkey,currentTime+timeout) 得到valueB,如果valueB ==null || valueA == valueB,获得锁操作步骤6,否则说明锁被其他线程获取了;
6、处理完业务逻辑,再去判断锁是否超时,如果没超时删除锁,如果已超时,不用处理。
流程如图:
1、客户端对某个方法加锁时,在zk上的与该方法对应的指定locker节点的目录下,生成一个唯一的瞬时有序节点node1;
2、客户端获取该路径下所有已经创建的子节点,如果发现自己创建的node1的序号是最小的,就认为这个客户端获得了锁;
3、如果发现node1不是最小的,则还没有获取到锁,监听比自己创建节点序号小的最大的节点,进入等待;
4、获取锁后,处理完逻辑,删除自己创建的node1;
5、删除4中监听节点,则客户端的Watcher会收到相应通知,此时再次判断自己创建的节点是否是locker子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。
流程如图: