锁 : Redission 分布式 锁
参考:https://github.com/redisson/redisson/wiki/8.-分布式锁和同步器
使用SpringBoot整合Redisson
一、引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.10.6</version>
</dependency>
二、application.properties中添加相关配置
#spring.redis.database=
spring.redis.host=localhost
spring.redis.port=6379
#spring.redis.password=
#spring.redis.ssl=
#spring.redis.timeout=
#spring.redis.cluster.nodes=
#spring.redis.sentinel.master=
#spring.redis.sentinel.nodes=
三、可重入锁
基于Redis的Redisson分布式可重入锁RLock,实现了java.util.concurrent.locks.Lock接口
RLock lock = redissonClient.getLock("ReentrantLock");
lock.lock();
如果负责存储这个分布式锁的Redis节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断地延长锁的有效期。默认情况下,看门狗检查锁的超时时间是30秒,也可以通过修改Config.lockWatchdogTimeout来另行指定
lock方法提供了leaseTime的参数来指定加锁的时间,超过这个时间自动解锁
//加锁10秒后自动解锁
lock.lock(10, TimeUnit.SECONDS);
//尝试加锁,最多等待2秒,加锁10秒后自动解锁,获取锁成功返回true,失败返回false
boolean result = lock.tryLock(2, 10, TimeUnit.SECONDS);
//解锁
lock.unlock();
可重入锁的大部分API后面几种锁都可以使用
可重入锁实现:
Redisson为分布式锁提供了异步执行的相关方法:
RLock lock = redissonClient.getLock("AsyncLock");
lock.lockAsync();
lock.lockAsync(10, TimeUnit.SECONDS);
lock.tryLockAsync(2,10,TimeUnit.SECONDS);
四、公平锁
分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的RLock对象。它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程
RLock fairLock = redissonClient.getFairLock("FairLock");
fairLock.lock();
五、联锁
分布式联锁RedissonMultiLock对象可以将多个RLock
对象关联为一个联锁,每个RLock对象实例可以来自于不同的Redisson实例
RLock lock1 = redissonClient.getLock("lock1");
RLock lock2 = redissonClient.getLock("lock2");
RLock lock3 = redissonClient.getLock("lock3");
RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
//同时加锁lock1、lock2、lock3,所有的锁都上锁成功才算成功
lock.lock();
六、红锁
红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例
RLock lock1 = redissonClient.getLock("lock1");
RLock lock2 = redissonClient.getLock("lock2");
RLock lock3 = null;
RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
//同时加锁lock1、lock2、lock3,红锁在大部分节点上加锁成功就算成功(N/2+1)
lock.lock();
七、读写锁
分布式可重入读写锁RReadWriteLock对象实现了java.util.concurrent.locks.ReadWriteLock接口。同时还支持自动过期解锁。该对象允许同时有多个读取锁,但是最多只能有一个写入锁
RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("ReadWriteLock");
// 读锁
readWriteLock.readLock().lock();
// 写锁
// readWriteLock.writeLock().lock();
八、信号量
分布式信号量RSemaphore对象采用了与java.util.concurrent.Semaphore相似的接口和用法
RSemaphore semaphore = redissonClient.getSemaphore("Semaphore");
//信号量为6
semaphore.acquire(6);
//在其他线程或其他JVM里释放信号量
RSemaphore semaphore = redissonClient.getSemaphore("Semaphore");
semaphore.release(1);
//在其他线程或其他JVM里释放信号量
RSemaphore semaphore = redissonClient.getSemaphore("Semaphore");
semaphore.release(5);
九、可过期性信号量
可过期性信号量RPermitExpirableSemaphore是在RSemaphore对象的基础上,为每个信号增加了一个过期时间。每个信号可以通过独立的ID来辨识,释放时只能通过提交这个ID才能释放
RPermitExpirableSemaphore semaphore = redissonClient.getPermitExpirableSemaphore("mySemaphore");
String permitId = semaphore.acquire();
// 获取一个信号,有效期只有2秒钟
String permitId = semaphore.acquire(2, TimeUnit.SECONDS);
semaphore.release(permitId);
十、闭锁
分布式闭锁RCountDownLatch对象采用了与java.util.concurrent.CountDownLatch相似的接口和用法
RCountDownLatch latch = redissonClient.getCountDownLatch("CountDownLatch");
latch.trySetCount(1);
latch.await();
//在其他线程或其他JVM里
RCountDownLatch latch = redissonClient.getCountDownLatch("CountDownLatch");
latch.countDown();