redisson 分布式锁必知必会
redisson 分布式锁必知必会
常用锁类型概览
| 锁类型 | 方法 | 特点 | 适用场景 |
|---|---|---|---|
| 阻塞锁 | lock() |
一直等待直到获取锁,默认看门狗续期。 | 必须串行执行的任务 |
| 阻塞锁 + 自动释放 | lock(time, unit) |
固定时间后释放,不依赖看门狗 | 业务耗时可预估 |
| 非阻塞锁 | tryLock() |
立即返回结果,不等待 | 实时性要求高 |
| 非阻塞锁 + 等待时间 | tryLock(waitTime, leaseTime, unit) |
可等待一段时间再放弃 | 可容忍短暂等待 |
| 可重入锁 |
RLock 默认支持 |
同一线程可多次加锁 | 递归调用、嵌套调用 |
| 公平锁 | getFairLock() |
按请求顺序获取锁 | 排队系统 |
| 读写锁 | getReadWriteLock() |
多读共享,写独占 | 读多写少 |
| 多锁 | getMultiLock() |
多个锁同时成功才算加锁成功 | 多资源一致性 |
配置 redisson 客户端
1
2
3
4
5
6
spring:
redis:
host: localhost
port: 6379
password:
database: 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.database}")
private int database;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://" + redisHost + ":" + redisPort)
.setPassword(password)
.setDatabase(database);
return Redisson.create(config);
}
}
阻塞锁(lock)
特点
- 会阻塞当前线程直到获取锁。
- 默认开启 看门狗机制(默认 30 秒),会自动续期,避免锁过期。
适用场景
- 必须保证顺序执行的任务,例如库存扣减、订单生成。
1
2
3
4
5
6
7
8
RLock lock = redisson.getLock("orderLock");
// 阻塞直到获取锁
lock.lock();
try {
processOrder();
} finally {
lock.unlock();
}
阻塞锁 + 自动释放时间
特点
- 不依赖看门狗,锁会在指定时间后自动释放。
- 适合业务执行时间可预估的场景。
注意
- 如果业务执行时间超过设定值,锁会提前释放,可能导致并发问题。
1
2
3
4
5
6
7
8
9
RLock lock = redisson.getLock("orderLock");
// 10 秒后自动释放
lock.lock(10, TimeUnit.SECONDS);
try {
// 业务逻辑
processOrder();
} finally {
lock.unlock();
}
非阻塞锁(tryLock)
特点
- 立即返回
true或false,不等待。- 成功加锁后,默认 30 秒超时,看门狗每 10 秒续期一次。
- 适合实时性要求高的场景。
1
2
3
4
5
6
7
8
9
10
RLock lock = redisson.getLock("orderLock");
if (lock.tryLock()) {
try {
processOrder();
} finally {
lock.unlock();
}
} else {
System.out.println("获取锁失败,执行降级逻辑。");
}
非阻塞锁 + 等待时间 + 自动释放时间
参数说明
waitTime:最大等待时间leaseTime:锁自动释放时间unit:时间单位适用场景
- 可容忍一定等待时间,但不希望无限阻塞。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
RLock lock = redisson.getLock("orderLock");
try {
if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
try {
processOrder();
} finally {
lock.unlock();
}
} else {
System.out.println("等待 5 秒仍未获取到锁");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
可重入锁
特点
RLock默认支持可重入,同一线程可多次加锁。注意
- 每次加锁都需要对应一次解锁,否则锁不会释放。
1
2
3
4
5
6
7
8
9
10
11
RLock lock = redisson.getLock("orderLock");
lock.lock();
// 同一线程可再次获取锁
lock.lock();
try {
processOrder();
} finally {
lock.unlock();
// 需要解锁两次
lock.unlock();
}
公平锁(FairLock)
特点
- 按请求顺序获取锁,避免“插队”。
适用场景
- 排队系统、严格先来先得的业务。
1
2
3
4
5
6
7
RLock fairLock = redisson.getFairLock("fairLock");
fairLock.lock();
try {
processOrder();
} finally {
fairLock.unlock();
}
读写锁(ReadWriteLock)
特点
- 读锁可共享,写锁独占。
- 读多写少时可显著提升并发性能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
RReadWriteLock rwLock = redisson.getReadWriteLock("rwLock");
// 读锁
rwLock.readLock().lock();
try {
readData();
} finally {
rwLock.readLock().unlock();
}
// 写锁
rwLock.writeLock().lock();
try {
writeData();
} finally {
rwLock.writeLock().unlock();
}
多锁(MultiLock)
特点
- 一次性获取多个锁,全部成功才算加锁成功。
- 适合需要同时锁定多个资源的场景。
1
2
3
4
5
6
7
8
9
10
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock multiLock = redisson.getMultiLock(lock1, lock2);
multiLock.lock();
try {
processMultiResource();
} finally {
multiLock.unlock();
}
本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0
许可协议,转载请注明出处!