前言
在分析Redisson分布式锁实现之前,不妨先看看接口定义,可以让源码的阅读更加顺畅,磨刀不误砍柴工。
接口中的方法不多,只有下面这十五个,其中很多看名称就大概知道其功能。
- forceUnlockAsync();
- unlockAsync();
- unlockAsync(long threadId);
- tryLockAsync();
- lockAsync();
- lockAsync(long threadId);
- lockAsync(long leaseTime, TimeUnit unit);
- lockAsync(long leaseTime, TimeUnit unit, long threadId);
- tryLockAsync(long threadId);
- tryLockAsync(long waitTime, TimeUnit unit);
- tryLockAsync(long waitTime, long leaseTime, TimeUnit unit);
- tryLockAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId);
- getHoldCountAsync();
- isLockedAsync();
- remainTimeToLiveAsync();
这里一一来说明
释放锁
forceUnlockAsync()
说明:如果指定的锁存在,则强制释放锁,不用判断锁是否有重入的情况。
unlockAsync()
说明:手动解锁,在方法内获取到当前线程id,调用的还是unlockAsync(long threadId);
@Override
public RFuture<Void> unlockAsync() {
long threadId = Thread.currentThread().getId();
return unlockAsync(threadId);
}
unlockAsync(long threadId)
说明:手动解锁,在各个锁类型中,实现各不相同。
一次性获取锁
用的指令集是RedisCommands.EVAL_NULL_BOOLEAN,在获取失败后,不会重新尝试获取。
tryLockAsync()
说明:获取锁,语法糖,实现中调用了其他方法
@Override
public RFuture<Boolean> tryLockAsync() {
return tryLockAsync(Thread.currentThread().getId());
}
tryLockAsync(long threadId)
说明:
@Override
public RFuture<Boolean> tryLockAsync(long threadId) {
return tryAcquireOnceAsync(-1, null, threadId);
}
多次尝试获取锁
用的指令集是RedisCommands.EVAL_LONG,在获取失败后,返回需要等待的时间,在等待时间内,重复尝试获取锁。
无限等待
lockAsync()
说明:这个方法是一个语法糖,实际调用的是接口中的其他方法,设定leaseTime为-1
@Override
public RFuture<Void> lockAsync() {
return lockAsync(-1, null);
}
lockAsync(long threadId)
说明:用指定的线程id来获取锁,同样是语法糖,看看其实现
@Override
public RFuture<Void> lockAsync(long currentThreadId) {
return lockAsync(-1, null, currentThreadId);
}
lockAsync(long leaseTime, TimeUnit unit)
说明:指定持有时间,尝试获取锁,注意这里是没有指定等待时间的。
@Override
public RFuture<Void> lockAsync(long leaseTime, TimeUnit unit) {
long currentThreadId = Thread.currentThread().getId();
return lockAsync(leaseTime, unit, currentThreadId);
}
lockAsync(long leaseTime, TimeUnit unit, long threadId)
说明:指定持有时间,尝试获取锁,注意这里是没有指定等待时间的。这个分支中,所有没有指定等待时间的方法糖都会指向到这里。而不指定等待时间,就是说客户端线程会无限等待。
有限时间等待
tryLockAsync(long waitTime, TimeUnit unit)
说明:指定等待时间,尝试获取锁。
@Override
public RFuture<Boolean> tryLockAsync(long waitTime, TimeUnit unit) {
return tryLockAsync(waitTime, -1, unit);
}
tryLockAsync(long waitTime, long leaseTime, TimeUnit unit)
说明:指定等待时间和持有时间,尝试获取锁。
@Override
public RFuture<Boolean> tryLockAsync(long waitTime, long leaseTime, TimeUnit unit) {
long currentThreadId = Thread.currentThread().getId();
return tryLockAsync(waitTime, leaseTime, unit, currentThreadId);
}
tryLockAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId)
说明:多次尝试获取锁的真正执行方法,这个分支中,所有指定等待时间的方法糖都指向这里。
其他方法
getHoldCountAsync()
说明:获取当前客户端线程持有锁的次数
public RFuture<Integer> getHoldCountAsync() {
return commandExecutor.writeAsync(getName(), LongCodec.INSTANCE, HGET, getName(), getLockName(Thread.currentThread().getId()));
}
isLockedAsync()
说明:判断资源锁是否被持有,非公平锁中值判断锁资源是否存在,而读写锁有特定的实现。
remainTimeToLiveAsync()
说明:锁资源的剩余存在时间
@Override
public RFuture<Long> remainTimeToLiveAsync() {
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.PTTL, getName());
}