Skip to content

分布式锁实现 ​

深入理解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源码深度解析