原理
就是开一个定时任务,,然后每隔10s检查一次,并将其续约恢复至我们设置的lockWatchdogTimeout(默
认是30s)
jvm挂了,看门狗会一直续期下去吗
挂了的话,不会一直续期的。看门狗是jvm线程,jvm挂了的话,会终止续期的
加锁线程挂了,但jvm没挂,看门狗会一直续期下去吗

看门狗线程本质就是一个守护线程,且这个线程是和加锁线程绑定的,或者说它续期会去判断加锁线程是否存
活,存活才会去续期
并非守护线程
源码解读
续期任务调度的实现
这个方法是为锁开启续期任务,且一把锁只会有一个续期任务!!!由第一个持有该锁的线程开启,后续第
n个持有该锁的线程只需要把threadId注册到一个concurrentHashMap里
为什么?
你续期任务本质就是一个开一个线程不断轮询,那一个线程配一个定时线程这显然是不合理的。肯定
是不合理的,只需要一把锁对应一个续期任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| protected void scheduleExpirationRenewal(long threadId) { ExpirationEntry entry = new ExpirationEntry(); ExpirationEntry oldEntry = (ExpirationEntry)EXPIRATION_RENEWAL_MAP.putIfAbsent(this.getEntryName(), entry); if (oldEntry != null) { oldEntry.addThreadId(threadId); } else { entry.addThreadId(threadId);
try { this.renewExpiration(); } finally { if (Thread.currentThread().isInterrupted()) { this.cancelExpirationRenewal(threadId); }
} }
}
|
续期的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
private void renewExpiration() { ExpirationEntry ee = (ExpirationEntry) EXPIRATION_RENEWAL_MAP.get(this.getEntryName()); if (ee != null) { Timeout task = this.getServiceManager().newTimeout(new TimerTask() { @Override public void run(Timeout timeout) throws Exception { ExpirationEntry ent = (ExpirationEntry) RedissonBaseLock.EXPIRATION_RENEWAL_MAP.get(RedissonBaseLock.this.getEntryName()); if (ent != null) { Long threadId = ent.getFirstThreadId(); if (threadId != null) {
CompletionStage<Boolean> future = RedissonBaseLock.this.renewExpirationAsync(threadId);
future.whenComplete((res, e) -> {
if (e != null) { RedissonBaseLock.log.error( "Can't update lock {} expiration", RedissonBaseLock.this.getRawName(), e ); RedissonBaseLock.EXPIRATION_RENEWAL_MAP.remove(RedissonBaseLock.this.getEntryName()); } else { if (res) { RedissonBaseLock.this.renewExpiration(); } else { RedissonBaseLock.this.cancelExpirationRenewal(null); } } }); } } } }, this.internalLockLeaseTime / 3L, TimeUnit.MILLISECONDS);
ee.setTimeout(task); } }
|
Redisson的定时任务是基于Netty中的时间轮来实现的
时间轮是什么?时间轮算法
Redisson执行定时任务的work线程
timer就是一个HashedWheelTimer(Netty的时间轮)

return 一个Timeout(表示你刚刚注册的这个定时任务,你可以通过这个timeout来查看任务状态等等)

newTimeout:往时间轮里面 注册一个定时任务
