水煮Redisson(十三)-锁接口方法分类

262 阅读3分钟

前言

在分析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());
    }