Redisson 还提供了自动续期的功能,通过定时任务(看门狗)定期延长锁的有效期,确保在业务未完成前,锁不会被其他线程获取。
<!-- Redisson --> <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.25.2</version> <!-- 请根据实际情况使用最新版本 --> </dependency>其他项目,访问 https://mvnrepository.com/search?q=Redisson 获取具体依赖配置。
import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RedissonConfig { @Bean public RedissonClient redissonClient() { Config config = new Config(); // 也可以将 redis 配置信息保存到配置文件 config.useSingleServer().setAddress("redis://127.0.0.1:6379"); return Redisson.create(config); } }③ 创建分布式锁
import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.TimeUnit; @RestController public class LockController { @Autowired private RedissonClient redissonClient; @GetMapping("/lock") public String lockResource() throws InterruptedException { String lockKey = "myLock"; // 获取 RLock 对象 RLock lock = redissonClient.getLock(lockKey); try { // 尝试获取锁(尝试加锁)(锁超时时间是 30 秒) boolean isLocked = lock.tryLock(30, TimeUnit.SECONDS); if (isLocked) { // 成功获取到锁 try { // 模拟业务处理 TimeUnit.SECONDS.sleep(5); return "成功获取锁,并执行业务代码"; } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放锁 lock.unlock(); } } else { // 获取锁失败 return "获取锁失败"; } } catch (InterruptedException e) { e.printStackTrace(); } return "获取锁成功"; } }a.实现公平锁
RLock lock = redissonClient.getFairLock(lockKey); // 获取公平锁b.实现读写锁
RReadWriteLock lock = redissonClient.getReadWriteLock(lockKey); // 获取读写锁 lock.readLock(); // 读锁 lock.writeLock(); // 写锁读写锁的特点就是并发性能高,它是允许多个线程同时获取读锁进行读操作的,也就是说在没有写锁的情况下,读取操作可以并发执行,提高了系统的并行度。但写锁则是独占式的,同一时间只有一个线程可以获得写锁,无论是读还是写都无法与写锁并存,这样就确保了数据修改时的数据一致性。
// 获取需要加锁的资源 RLock lock1 = redisson.getLock("lock1"); RLock lock2 = redisson.getLock("lock2"); // 联锁 RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2); try { // 一次性尝试获取所有锁 if (multiLock.tryLock()) { // 获取锁成功... } } finally { // 释放所有锁 multiLock.unlock(); }总结