1、redisson概述
Redisson是一个分布式协调Redis客服端,实现了大部分java环境下分布式对象,如锁分布式锁和同步器、对象桶(Object Bucket)、二进制流(Binary Stream)、地理空间对象桶(Geospatial Bucket)、BitSet、原子整长形(AtomicLong)、原子双精度浮点数(AtomicDouble)、话题(订阅分发)、模糊话题、布隆过滤器(Bloom Filter)、基数估计算法(HyperLogLog)等。
2、 redissonLock 比setnx有哪些优势
- 实现可重入锁机制。
- 实现在一定的waittime内等待重试获取锁。
- 实现看门狗定时刷新过期时间——锁续约机制。
- 只有用户没有设置leaseTime超时时间,那么才会使用默认的超时时间,也就是看门狗时间=30s,定时任务也是1/3 * 看门狗时间(30s)的延时任务刷新超时时间。
- 实现多节点保存同一把锁,防止主从不一致问题。
-
redis主从结构,一般主写从读,获取锁则是写操作,当A获取锁失败,此时主从尚未同步之前,主宕机,从选举为主,此时锁没了,其他用户还能获取锁。

-
3、分布式锁RedissonLock
RedissonLock 使用 Redis Hash 数据结构来承载锁的抢占与释放,锁标识为自定义key, 如lock:order:userID, Hash 中的 filed 由UUID.toString():Thread.currentThread().getId()拼接而成,value 值一般为 1 (重入次数自增)。
本章主要研究可重入式分布式锁RedissonLock,其JAVA 代码创建如下:
Config config = new Config();
config.useSingleServer().setAddress("redis://ip:6379").setPassword("123");
Redisson redisson = Redisson.create(config);
// 使用redisson 自带的分布式锁
RLock redisLock = redissonClient.getLock("voucherOrder");
if (!redisLock.tryLock()) {
return Result.fail("禁止重复参与!");
}
try {
IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
return proxy.createVoucherOrder(voucherId);
} finally {
redisLock.unlock();
}
4、RedissonLock代码解析
上述例子中,主要是tryLock和unlock接口,先看tryLock接口。
public boolean tryLock() {
return get(tryLockAsync());
}
public boolean tryLock(long waitTime, TimeUnit unit) throws InterruptedException {
return tryLock(waitTime, -1, unit);
}
/**
* 等待异步回调结果,若future执行成功则返回结果。
* 在此:返回的是
*/
public <V> V get(RFuture<V> future) {
try {
future.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (future.isSuccess()) {
return future.getNow();
}
throw convertException(future);
}
进入trylock()方法
// waitTime : 等待重试获取锁时间
// leaseTime : 锁超时释放事件
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long time = unit.toMillis(waitTime);
long current = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
Long ttl = tryAcquire(waitTime, leaseTime, unit, threadId);
// lock acquired
if (ttl == null) {
return true;
}
time -= System.currentTimeMillis() - current;
if (time <= 0) {
acquireFailed(waitTime, unit, threadId);
return false;
}
current = System.currentTimeMillis();
RFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId);
if (!subscribeFuture.await(time, TimeUnit.MILLISECONDS)) {
if (!subscribeFuture.cancel(false

本文详细介绍了Redisson分布式锁RedissonLock的特点,包括其与setnx的优势比较,重点剖析了RedissonLock的加锁和解锁机制,以及如何实现可重入锁、锁续约和防止主从一致性问题。
最低0.47元/天 解锁文章
5863

被折叠的 条评论
为什么被折叠?



