Redisson是一个用于Redis的Java客户端,它极大地简化了分布式锁、分布式集合、分布式服务等复杂场景下的开发工作。Redisson提供了丰富的功能,并且对分布式锁的支持尤为强大和灵活。
引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.20.0</version>
</dependency>
创建配置类
@Configuration
public class RedissonConfig {
@Bean("redissonClient")
public RedissonClient redissonClient() {
Config config = new Config();
String redisHost = "127.0.0.1";
String password = "Aa123456@";
Integer port = 6379;
int dbNo = 0;
config.useSingleServer()
.setAddress("redis://" + redisHost + ":" + port)
.setDatabase(dbNo)
.setPassword(password);
// 创建RedissonClient对象
return Redisson.create(config);
}
}
方式1:基本使用(自动续期)
lock.lock();
方式2:指定租约时间(无自动续期)
对象.lock(10, TimeUnit.SECONDS);
方式3:尝试获取锁(推荐)
boolean acquired = 对象.tryLock(10, 30, TimeUnit.SECONDS);
1.可重入锁(Reentrant Lock)
是最常用的锁类型之一,类似于Java中的ReentrantLock。
在某些复杂的业务逻辑中,一个方法可能会调用另一个方法,而这两个方法都需要获取同一把锁。如果使用普通的锁,线程在第一次获取锁后,再次尝试获取锁时会被阻塞。可重入锁允许同一个线程多次获取锁,避免了这种情况。
private RedissonClient redissonClient;
public void performTask() throws InterruptedException {
RLock lock = redissonClient.getLock("myLock");
try {
// 尝试获取锁,最多等待10秒,持有锁的时间为60秒
boolean isLocked = lock.tryLock(10, 60, TimeUnit.SECONDS);
if (isLocked) {
// 执行业务逻辑
}
} finally {
lock.unlock(); // 确保释放锁
}
}
2.公平锁(Fair Lock)
公平锁确保所有请求按照它们到达的顺序获取锁,避免“饥饿”现象。
private RedissonClient redissonClient;
public void performTask() throws InterruptedException {
RLock fairLock = redissonClient.getFairLock("myFairLock");
try {
fairLock.lock(10, TimeUnit.SECONDS); // 获取锁并设置最大等待时间
//fairLock.tryLock(10,60,TimeUnit.SECONDS);
// 执行业务逻辑
} finally {
fairLock.unlock();
}
}
3.读写锁(ReadWriteLock)
读写锁允许多个线程同时读取数据,但在写入时提供独占访问。
private RedissonClient redissonClient;
public void read() throws InterruptedException {
//获取读写锁对象
RReadWriteLock rwLock = redissonClient.getReadWriteLock("myReadWriteLock");
rwLock.readLock().lock();
try {
// 执行读操作
} finally {
rwLock.readLock().unlock();
}
}
public void write() throws InterruptedException {
//获取读写锁对象
RReadWriteLock rwLock = redissonClient.getReadWriteLock("myReadWriteLock");
rwLock.writeLock().lock();
try {
// 执行写操作
} finally {
rwLock.writeLock().unlock();
}
}
4.联锁(MultiLock)
联锁是一种同步机制,用于同时获取多个锁。在分布式系统中,当需要对多个独立资源进行操作时,联锁确保所有的资源都被锁定,以进行安全的原子操作。
private RedissonClient redissonClient;
public void performTask() throws InterruptedException {
RLock lock1 = redissonClient.getLock("lock1");
RLock lock2 = redissonClient.getLock("lock2");
RLock multiLock = redissonClient.getMultiLock(lock1, lock2);
try {
multiLock.lock();
// 执行业务逻辑
} finally {
multiLock.unlock();
}
}
5.自旋锁(Spin Lock)
自旋锁是一种非阻塞锁,线程在获取锁时会不断尝试,直到成功为止。
private RedissonClient redissonClient;
public void performTask() throws InterruptedException {
RLock spinLock = redissonClient.getSpinLock("mySpinLock");
try {
spinLock.lock();
// 执行业务逻辑
} finally {
spinLock.unlock();
}
}
7.红锁(RedLock)
在多个独立的 Redis 节点上同时获取锁,只有当大多数节点(N/2 + 1)都成功获取锁时,才认为锁获取成功。
备注:当你在类的构造器、字段(成员变量)或 setter 方法上使用 @Autowired 时,Spring 容器会尝试找到匹配的 Bean 并将其注入到相应的属性中。这极大地简化了对象之间的依赖管理,减少了样板代码,并提高了代码的可维护性和灵活性。
创建多节点配置类
@Configuration
public class RedissonConfig {
@Bean(name = "client1", destroyMethod = "shutdown")
public RedissonClient createClient1() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://127.0.0.1:6379")
.setPassword("password1") // 如果有密码
.setDatabase(0); // 选择数据库
return Redisson.create(config);
}
@Bean(name = "client2", destroyMethod = "shutdown")
public RedissonClient createClient2() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://127.0.0.1:6380")
.setPassword("password2") // 如果有密码
.setDatabase(0); // 选择数据库
return Redisson.create(config);
}
@Bean(name = "client3", destroyMethod = "shutdown")
public RedissonClient createClient3() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://127.0.0.1:6381")
.setPassword("password3") // 如果有密码
.setDatabase(0); // 选择数据库
return Redisson.create(config);
}
}
实现工具类
@Component
public class RedissonUtil {
private final RedissonClient client1;
private final RedissonClient client2;
private final RedissonClient client3;
@Autowired
public RedissonUtil(@Qualifier("client1") RedissonClient client1,
@Qualifier("client2") RedissonClient client2,
@Qualifier("client3") RedissonClient client3) {
this.client1 = client1;
this.client2 = client2;
this.client3 = client3;
}
public boolean tryRedLock(String lockName, long waitTime, long leaseTime, TimeUnit timeUnit) {
RLock lock1 = client1.getLock(lockName);
RLock lock2 = client2.getLock(lockName);
RLock lock3 = client3.getLock(lockName);
RLock redLock = client1.getRedLock(lock1, lock2, lock3);
try {
return redLock.tryLock(waitTime, leaseTime, timeUnit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
public void releaseRedLock(String lockName) {
RLock lock1 = client1.getLock(lockName);
RLock lock2 = client2.getLock(lockName);
RLock lock3 = client3.getLock(lockName);
RLock redLock = client1.getRedLock(lock1, lock2, lock3);
if (redLock.isLocked() && redLock.isHeldByCurrentThread()) {
redLock.unlock();
}
}
}
代码示例
@Service
public class RedisService {
private final RedissonUtil redissonUtil;
@Autowired
public RedisService(RedissonUtil redissonUtil) {
this.redissonUtil = redissonUtil;
}
public void performTask() throws InterruptedException {
boolean isLocked = redissonUtil.tryRedLock("myRedLock", 100, 10, TimeUnit.SECONDS);
if (isLocked) {
try {
System.out.println("RedLock acquired successfully!");
// 执行业务逻辑
Thread.sleep(1000L);
} finally {
redissonUtil.releaseRedLock("myRedLock");
System.out.println("RedLock released!");
}
} else {
System.out.println("Failed to acquire RedLock!");
}
}
}
1726

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



