溪云阁:专注编程教学,架构,JAVA,Python,微服务,机器学习等领域,欢迎关注,一起学习。
前言
上一篇文章我们介绍了Redisson的原理,《面试不消怕,用最普通易懂的语言,3分钟记分布式锁Redisson原理》,太过底层了很少人看,确实非常枯燥,但是这两篇却是满满的干货,希望各位看官能认真看完并明白内里的东西,你就会发现原来“锁”是这么简单。
版本
目前我们用最新版本来做源码分析,看看究竟用了什么
org.redisson redisson 3.16.3 Redisson的核心
全局来看整个Redisson,最核心的接口就是RLock,最核心的实现类就是RedissonLock。
上次我们用springboot整合Redisson的文章《Springboot实现高性能分布式锁-Redission》内里涉及到的注入获取锁,我猜测就是直接注入RedissonLock
final RLock lock = redissonClient.getLock(lockKey);RLock接口
public interface RLock extends Lock, RLockAsync { String getName(); // 中断锁 表现该锁可以被中断 如果A和B同时调这个方法,A获取锁,B为获取锁,那么B线程可以通过 // Thread.currentThread().interrupt(); 方法真正中断该线程 void lockInterruptibly(long var1, TimeUnit var3) throws InterruptedException; // 在一定时间内获取锁,如果拿到了返回true,如果拿不到返回false boolean tryLock(long var1, long var3, TimeUnit var5) throws InterruptedException; // 加锁,默认时间为30秒 void lock(long var1, TimeUnit var3); // 欺压解锁 boolean forceUnlock(); // 判断是否被锁住 boolean isLocked(); // 检测锁是否被线程获得 boolean isHeldByThread(long var1); // 检测当前线程是否获得锁 boolean isHeldByCurrentThread(); // 获取当前正在持有锁的线程的个数 int getHoldCount(); // 获取该锁的剩余时间 long remainTimeToLive();}从整个接口上来看,直接集成了Java的Lock,以及自己的RlockAsync,来看看RlockAsync究竟做了什么事
public interface RLockAsync { RFuture forceUnlockAsync(); RFuture unlockAsync(); RFuture unlockAsync(long var1); RFuture tryLockAsync(); RFuture lockAsync(); RFuture lockAsync(long var1); RFuture lockAsync(long var1, TimeUnit var3); RFuture lockAsync(long var1, TimeUnit var3, long var4); RFuture tryLockAsync(long var1); RFuture tryLockAsync(long var1, TimeUnit var3); RFuture tryLockAsync(long var1, long var3, TimeUnit var5); RFuture tryLockAsync(long var1, long var3, TimeUnit var5, long var6); RFuture getHoldCountAsync(); RFuture isLockedAsync(); RFuture remainTimeToLiveAsync();}RlockAsync用了RFuture的东西,继续往下走的时候发现RFuture直接集成Futrue,那统统都好说了,猜测加锁用了异步的方式
public interface RFuture extends Future, CompletionStage RedissonLock实现类
public class RedissonLock extends RedissonBaseLock public abstract class RedissonBaseLock extends RedissonExpirable implements RLock 从这两个继承可以很明显看到分布式锁本质上是JAVA的锁+过期时间+异步进行奇妙的组合
我们直接来看lock是怎么实现的
private void lock(long leaseTime, TimeUnit unit, boolean interruptibly) throws InterruptedException { long threadId = Thread.currentThread().getId(); Long ttl = this.tryAcquire(-1L, leaseTime, unit, threadId); if (ttl != null) { RFuture future = this.subscribe(threadId); if (interruptibly) { this.commandExecutor.syncSubscriptionInterrupted(future); } else { this.commandExecutor.syncSubscription(future); } try { while(true) { ttl = this.tryAcquire(-1L, leaseTime, unit, threadId); if (ttl == null) { return; } if (ttl >= 0L) { try { ((RedissonLockEntry)future.getNow()).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } catch (InterruptedException var13) { if (interruptibly) { throw var13; } ((RedissonLockEntry)future.getNow()).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } } else if (interruptibly) { ((RedissonLockEntry)future.getNow()).getLatch().acquire(); } else { ((RedissonLockEntry)future.getNow()).getLatch().acquireUninterruptibly(); } } } finally { this.unsubscribe(future, threadId); } } }非常好明白的代码,像我们昨天说的,获取锁不到的话直接一直while进行循环,真的是简单粗暴+有用,各位有兴趣的同学可以按照我的方式去研究,在研究之前建议先认识Lock,Furture两种。
--END--
作者:@溪云阁
原创作品,抄袭必究
如需要源码,请转发,关注后私信我
部分图片或代码泉源网络,如侵权请接洽删除,谢谢! |