Redis系列-生产应用篇-分布式锁(5)-单进程Redis分布式锁的Java实现(Redisson使用与底层实现)-原子锁类

Redisson单进程Redis分布式乐观锁的使用与实现

本文基于Redisson 3.7.5

4. 原子锁类

Redisson中实现了两种原子锁类:RAtomicLong和RAtomicDouble,还有RLongAdder和RDoubleAdder

RAtomicDouble和RAtomicLong其实一样的,RLongAdder和RDoubleAdder其实原理也是一样的,这里我们只说RAtomicLong和RLongAdder。

4.1. RedissonAtomicLong - 基于Redis实现的原子Long类

原子类的incrementAndGet,decrementAndGet,addandGet,主要通过INCR,DECR,INCRBY,DECRBY实现,其实redis的这些操作本身就是原子性的。

@Override
public RFuture<Long> getAndAddAsync(final long delta) {
    //getAndAdd通过INCRBY实现
    return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, new RedisStrictCommand<Long>("INCRBY", new SingleConvertor<Long>() {
        @Override
        public Long convert(Object obj) {
            return ((Long) obj) - delta;
        }
    }), getName(), delta);
}
@Override
public RFuture<Long> getAndSetAsync(long newValue) {
    //getAndSet通过GetSet实现
    return commandExecutor.writeAsync(getName(), LongCodec.INSTANCE, RedisCommands.GETSET, getName(), newValue);
}
@Override
public RFuture<Long> incrementAndGetAsync() {
    //incrementAndGet通过INCR实现
    return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, RedisCommands.INCR, getName());
}
@Override
public RFuture<Long> decrementAndGetAsync() {
    //减一通过DECR实现
    return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, RedisCommands.DECR, getName());
}

那么CAS更新呢?可以利用lua脚本的特性,也就是因为redis是单线程的,同时只能处理一个lua脚本,所以lua脚本具有原子性。

@Override
public RFuture<Boolean> compareAndSetAsync(long expect, long update) {
    //CAS操作
    //通过lua脚本的特性实现,lua脚本的原子性
    //先检查值是否符合,如果符合再更新,返回true,否则返回false
    return commandExecutor.evalWriteAsync(getName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
              "local currValue = redis.call('get', KEYS[1]); "
              + "if currValue == ARGV[1] "
                      + "or (tonumber(ARGV[1]) == 0 and currValue == false) then "
                 + "redis.call('set', KEYS[1], ARGV[2]); "
                 + "return 1 "
               + "else "
                 + "return 0 "
               + "end",
            Collections.<Object>singletonList(getName()), expect, update);
}

4.2. RedissonLongAdder 基于Redis实现的LongAdder

在统计场景下(写多读少,且数值不用考虑并发安全),LongAdder表现比AtomicLong更好,那么基于redis是怎么实现呢?
Redisson的实现思路比较简单,本地留存一个longAdder,只有调用get或者sum的时候,才把本地的longAdder的数值加到redis中。

public class RedissonLongAdder extends RedissonBaseAdder<Long> implements RLongAdder {
    //利用RAtomicLong实现redis中保存的数值
    private final RAtomicLong atomicLong;
    //本地longAdder
    private final LongAdder counter = new LongAdder();
}

统计但不get的操作都是对于本地longAdder操作:

@Override
public void add(long x) {
    counter.add(x);
}

@Override
public void increment() {
    add(1L);
}

@Override
public void decrement() {
    add(-1L);
}

与get还有sum相关的操作会把本地longAdder的数值加到redis中:

@Override
protected RFuture<Long> addAndGetAsync() {
    return atomicLong.getAndAddAsync(counter.sum());
}
@Override
protected RFuture<Long> getAndDeleteAsync() {
    return atomicLong.getAndDeleteAsync();
}
@Override
public long sum() {
    return get(sumAsync());
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redisson是基于Redis实现Java驻留内存数据网格的开源框架,提供了丰富的分布式锁实现方式。下面介绍基于Redisson的最优实现。 1. 初始化Redisson客户端 ```java Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); RedissonClient redisson = Redisson.create(config); ``` 2. 获取分布式锁 ```java RLock lock = redisson.getLock("myLock"); lock.lock(); try { // 业务逻辑 } finally { lock.unlock(); } ``` 3. 设置加超时时间和释放时限制 ```java RLock lock = redisson.getLock("myLock"); boolean locked = lock.tryLock(10, 60, TimeUnit.SECONDS); try { if (locked) { // 业务逻辑 } else { // 获取失败 } } finally { if (locked) { lock.unlock(); } } ``` 4. 实现可重入 ```java RLock lock = redisson.getLock("myLock"); lock.lock(); try { lock.lock(); try { // 业务逻辑 } finally { lock.unlock(); } } finally { lock.unlock(); } ``` 5. 实现公平 ```java RLock lock = redisson.getFairLock("myFairLock"); lock.lock(); try { // 业务逻辑 } finally { lock.unlock(); } ``` 6. 实现读写 ```java RReadWriteLock rwlock = redisson.getReadWriteLock("myReadWriteLock"); rwlock.readLock().lock(); try { // 读操作业务逻辑 } finally { rwlock.readLock().unlock(); } rwlock.writeLock().lock(); try { // 写操作业务逻辑 } finally { rwlock.writeLock().unlock(); } ``` 以上就是基于Redisson实现Redis分布式锁的最优实现Redisson提供了丰富的分布式锁实现,可以根据业务需求选择合适的锁类型。同时,Redisson还提供了许多其他功能,如分布式对象、分布式限流等,可以方便地实现分布式应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值