您的位置:首页 > 健康 > 养生 > 江苏疫情最新消息2023_金湖网站建设公司_石家庄疫情最新消息_百度app营销软件

江苏疫情最新消息2023_金湖网站建设公司_石家庄疫情最新消息_百度app营销软件

2025/2/24 10:16:44 来源:https://blog.csdn.net/weixin_44929475/article/details/144307887  浏览:    关键词:江苏疫情最新消息2023_金湖网站建设公司_石家庄疫情最新消息_百度app营销软件
江苏疫情最新消息2023_金湖网站建设公司_石家庄疫情最新消息_百度app营销软件

官方文档:Redisson参考指南

分布式锁案例

RLock lock = redissonClient.getLock("test_lock");
lock.lock();
try {log.info("lock success");Thread.sleep(10000);
} catch (InterruptedException e) {e.printStackTrace();
} finally {lock.unlock();
}

Redisson分布式锁中的Lua脚本主要在两个核心方法中被调用:

tryAcquireAsync用于加锁。

unlockInnerAsync用于解锁。

源码:

加锁Lua脚本(tryAcquireAsync

org.redisson.RedissonLock#tryLockInnerAsync

<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId,RedisStrictCommand<T> command) {return this.evalWriteAsync(this.getRawName(), LongCodec.INSTANCE, command, "if (redis.call('exists', KEYS[1]) == 0) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);", Collections.singletonList(this.getRawName()), new Object[]{unit.toMillis(leaseTime), this.getLockName(threadId)});
}
if (redis.call('exists', KEYS[1]) == 0) thenredis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; 
end;
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; 
end;
return redis.call('pttl', KEYS[1]);

如果锁不存在(exists返回0),则创建锁并设置过期时间(pexpire)。如果锁已存在并且当前线程已持有锁(通过hexists检查),则增加重入次数(hincrby)并重置过期时间。

解锁Lua脚本(unlockInnerAsync

org.redisson.RedissonBaseLock#unlockInnerAsync

protected RFuture<Boolean> unlockInnerAsync(long threadId) {return this.evalWriteAsync(this.getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, "if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]);redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;", Arrays.asList(this.getRawName(), this.getChannelName()), new Object[]{LockPubSub.UNLOCK_MESSAGE, this.internalLockLeaseTime, this.getLockName(threadId)});
}
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) thenreturn nil;
end;
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) thenredis.call('pexpire', KEYS[1], ARGV[2]);return 0;
elseredis.call('del', KEYS[1]);redis.call('publish', KEYS[2], ARGV[1]);return 1;
end;
return nil;

        如果锁存在并且是当前线程持有的(通过hexists检查),则减少重入次数(hincrby)。如果重入次数大于0,则更新过期时间(pexpire)。如果重入次数为0,则删除锁(del)并通过publish发布解锁消息,以便唤醒等待的线程。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com