分布式锁实现
深入理解Redisson分布式锁的实现原理,掌握可重入锁、读写锁、信号量、闭锁、公平锁等分布式同步工具的源码实现。
📋 分布式锁概览
分布式锁是分布式系统中的核心功能,Redisson提供了多种分布式锁实现。
🎯 一、可重入锁
1.1 RLock接口
RLock是Redisson可重入锁的接口:
java
public interface RLock extends Lock, RLockAsync {
void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException;
boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)
throws InterruptedException;
void unlock();
boolean isLocked();
boolean isHeldByCurrentThread();
int getHoldCount();
}1.2 加锁实现
RedissonLock.lock:
java
@Override
public void lock() {
try {
lock(-1, null, false);
} catch (InterruptedException e) {
throw new IllegalStateException();
}
}
private void lock(long leaseTime, TimeUnit unit, boolean interruptibly)
throws InterruptedException {
long threadId = Thread.currentThread().getId();
Long ttl = tryAcquire(leaseTime, unit, threadId);
if (ttl == null) {
return;
}
RFuture<RedissonLockEntry> future = subscribe(threadId);
if (interruptibly) {
commandExecutor.syncSubscriptionInterrupted(future);
} else {
commandExecutor.syncSubscription(future);
}
try {
while (true) {
ttl = tryAcquire(leaseTime, unit, threadId);
if (ttl == null) {
break;
}
if (ttl >= 0) {
try {
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);
}
}1.3 锁续期
Redisson通过看门狗机制实现锁的自动续期:
watchdog实现:
java
private void scheduleExpirationRenewal(long threadId) {
ExpirationEntry entry = new ExpirationEntry();
ExpirationEntry oldEntry = EXPIRATION_RENEWAL_MAP.putIfAbsent(getEntryName(), entry);
if (oldEntry != null) {
oldEntry.addThreadId(threadId);
} else {
entry.addThreadId(threadId);
renewExpiration();
}
}
private void renewExpiration() {
ExpirationEntry ee = EXPIRATION_RENEWAL_MAP.get(getEntryName());
if (ee == null) {
return;
}
Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
if (ent == null) {
return;
}
Long threadId = ent.getFirstThreadId();
if (threadId == null) {
return;
}
RFuture<Boolean> future = renewExpirationAsync(threadId);
future.onComplete((res, e) -> {
if (e != null) {
log.error("Can't update lock " + getName() + " expiration", e);
return;
}
if (res) {
renewExpiration();
}
});
}
}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
ee.setTimeout(task);
}🎯 二、读写锁
2.1 RReadWriteLock接口
RReadWriteLock是Redisson读写锁的接口:
java
public interface RReadWriteLock extends RObject {
RLock readLock();
RLock writeLock();
}2.2 读写锁实现
读写锁允许多个读锁同时持有,但写锁是独占的:
RedissonReadWriteLock:
java
public class RedissonReadWriteLock extends RedissonObject implements RReadWriteLock {
@Override
public RLock readLock() {
return new RedissonReadLock(commandExecutor, getName());
}
@Override
public RLock writeLock() {
return new RedissonWriteLock(commandExecutor, getName());
}
}📖 学习资源
视频教程
书籍推荐
- 《Redis设计与实现》 - 黄健宏
- 《分布式系统常用技术及案例分析》 - 柳伟卫
网站资源
✅ 学习检查清单
- [ ] 已理解可重入锁实现
- [ ] 已理解读写锁实现
- [ ] 已理解信号量实现
- [ ] 已理解闭锁实现
- [ ] 已理解锁续期机制
- [ ] 已绘制分布式锁流程图
- [ ] 已总结核心知识点
上一章节:连接管理深度解析
下一章节:分布式对象
返回目录:Redisson源码深度解析