Redission
温馨提示:
本文最后更新于 2022年10月27日,已超过 918 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
官方文档 https://github.com/redisson/redisson
一 加入redission依赖
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.8</version>
</dependency>
二 配置
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 MyRedissonConfig {
@Bean(destroyMethod="shutdown")
public RedissonClient redission(){
Config config = new Config();
//报错This instance has cluster support disabled 此实例已禁用群集支持,采用下面单节点配置方式
config.useClusterServers()
//可以用"rediss://"来启用SSL连接
.addNodeAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
return 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 MyRedissonConfig {
@Bean(destroyMethod="shutdown")
public RedissonClient redission(){
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.101.164:6379");
// config.useClusterServers()
//可以用"rediss://"来启用SSL连接
// .addNodeAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
return redisson;
}
三 分布式锁
获取分布式锁,进行加锁(加锁过程是一个阻塞过程,没有获取到锁的线程会一直等待到获取锁)。加锁成功后执行业务代码,最后再释放锁 。
@GetMapping("/hello")
public R hello(){
//1获取锁
RLock lock = redissonClient.getLock("my-lock");
//2手动加锁
lock.lock();
// lock.lock(10,TimeUnit.SECONDS);
//3执行业务代码
try {
System.out.println("加锁成功,正在执行业务代码。。。。"+Thread.currentThread().getId());
TimeUnit.SECONDS.sleep(10);
// Thread.sleep(30000);
}catch (Exception e){
}finally {
//4释放锁
System.out.println("释放锁成功");
lock.unlock();
}
return R.ok().put("data","测试成功");
}
1.直接加锁
lock.lock();该方法默认超时时间为30s,有看门狗给锁自动续过期时间(1/3超时时间续期一次)。当服务停止 导致不能释放锁。看门狗则不会再自动续期时间。
2. 超时加锁
lock.lock(10,TimeUnit.SECONDS); 在指定时间内获取锁,如果获取不到锁,则不再等待获取锁。
加锁底层源码:
private <T> RFuture<Long> tryAcquireAsync(long leaseTime, TimeUnit unit, long threadId) {
//leaseTime设置的等待时间,如果设置了,直接走加锁流程。
if (leaseTime != -1) {
return tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG);
}
//否则进入以下代码,看门狗自动续过期时间
RFuture<Long> ttlRemainingFuture = tryLockInnerAsync(commandExecutor.getConnectionManager().getCfg().getLockWatchdogTimeout(), TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);
ttlRemainingFuture.onComplete((ttlRemaining, e) -> {
if (e != null) {
return;
}
// lock acquired
if (ttlRemaining == null) {
scheduleExpirationRenewal(threadId);
}
});
return ttlRemainingFuture;
}
四 读写锁
四种模式
读+读 相当于没有加锁
读+写 读写操作互不影响
写+读 读操作只能等写操作完成才能获取锁
写+写 写操作阻塞,其他的写操作只能等前一个写操作完成才能获取锁
@ResponseBody
@GetMapping("/read")
public String readLock(){
//1获取读取锁
RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
//2 获取读锁
RLock rLock = readWriteLock.readLock();
//3加锁
rLock.lock();
String val = "";
try {
val = redisUtil.getKey("uuid");
}catch (Exception e){
}finally {
//4释放锁
rLock.unlock();
}
return val;
}
@ResponseBody
@GetMapping("/write")
public String writeLock(){
//1获取读取锁
RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
//2 获取写锁
RLock rLock = readWriteLock.writeLock();
//3加锁
rLock.lock();
String val = "";
try {
val = UUID.randomUUID().toString();
redisUtil.setKey("uuid",val);
TimeUnit.SECONDS.sleep(10);
}catch (Exception e){
}finally {
//4释放锁
rLock.unlock();
}
return val;
}
五 信号量
给信号量对应的锁设置值(信号量值),然后才能使用信号量。当信号量打满后,其他线程只能等待获取。或者获取失败后返回对应的信息
park.tryAcquire();//获取锁,返回true 或false
park.acquire();//获取锁,阻塞,一直等待
/**
* remark:信号量测试
* 信号量原本值有才能占用成功
* tryAcquire尝试获取信号量,成功返回true 失败返回false 可以用于限流
*/
@ResponseBody
@GetMapping("/park")
public String park(){
RSemaphore park = redissonClient.getSemaphore("park");
boolean b = park.tryAcquire();
try {
// park.acquire();
} catch (Exception e) {
e.printStackTrace();
}
return "停车成功";
}
@ResponseBody
@GetMapping("/gogo")
public String gogo(){
RSemaphore park = redissonClient.getSemaphore("park");
try {
park.release();
} catch (Exception e) {
e.printStackTrace();
}
return "离场成功";
}
六 闭锁
等待执行达到指定数量时,再执行。
/**
* remark:
* 闭锁(CountDownLatch)
* 等待所有线程执行完毕再执行
*
*/
@ResponseBody
@GetMapping("/close")
public String close() throws InterruptedException {
RCountDownLatch countDownLatch = redissonClient.getCountDownLatch("holiday-clock");
countDownLatch.trySetCount(5L);
countDownLatch.await();
return "保安关门成功,学校放假了。。。。。。";
}
@ResponseBody
@GetMapping("/goHome/{id}")
public String goHome(@PathVariable Long id) throws InterruptedException {
RCountDownLatch countDownLatch = redissonClient.getCountDownLatch("holiday-clock");
countDownLatch.countDown();
return id+"班放学了。。。。。";
}
正文到此结束
- 本文标签: Java
- 本文链接: https://www.tianyajuanke.top/article/20
- 版权声明: 本文由吴沛芙原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权