Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端 (2)

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

  id 值就是一个 UUID,客户端启动时生成

  那么这个 id 有什么用,大家暂且在脑中留下这个疑问,我们接着往下看

锁的获取

  我们从 lock 开始跟源码

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

  最终会来到有三个参数的 lock 方法

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

Redisson 分布式锁实现之源码篇 → 为什么推荐用 Redisson 客户端

private void lock(long leaseTime, TimeUnit unit, boolean interruptibly) throws InterruptedException { long threadId = Thread.currentThread().getId(); // 尝试获取锁;ttl为null表示锁获取成功; ttl不为null表示获取锁失败,其值为其他线程占用该锁的剩余时间 Long ttl = tryAcquire(-1, leaseTime, unit, threadId); // lock acquired if (ttl == null) { return; } // 锁被其他线程占用而获取失败,使用redis的发布订阅功能来等待锁的释放通知,而非自旋监测锁的释放 RFuture<RedissonLockEntry> future = subscribe(threadId); // 当前线程会阻塞,直到锁被释放时当前线程被唤醒(有超时等待,默认 7.5s,而不会一直等待) // 持有锁的线程释放锁之后,redis会发布消息,所有等待该锁的线程都会被唤醒,包括当前线程 if (interruptibly) { commandExecutor.syncSubscriptionInterrupted(future); } else { commandExecutor.syncSubscription(future); } try { while (true) { // 尝试获取锁;ttl为null表示锁获取成功; ttl不为null表示获取锁失败,其值为其他线程占用该锁的剩余时间 ttl = tryAcquire(-1, leaseTime, unit, threadId); // lock acquired if (ttl == null) { break; } // waiting for message if (ttl >= 0) { try { // future.getNow().getLatch() 返回的是 Semaphore 对象,其初始许可证为 0,以此来控制线程获取锁的顺序 // 通过 Semaphore 控制当前服务节点竞争锁的线程数量 future.getNow().getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { if (interruptibly) { throw e; } future.getNow().getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } } else { if (interruptibly) { future.getNow().getLatch().acquire(); } else { future.getNow().getLatch().acquireUninterruptibly(); } } } } finally { // 退出锁竞争(锁获取成功或者放弃获取锁),则取消锁的释放订阅 unsubscribe(future, threadId); } // get(lockAsync(leaseTime, unit)); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyppdw.html