基于Redis实现分布式锁
添加Redis的POM依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
使用自动装配引入 redis的 redisTemplate这里使用的是 StringRedisTemplate,
@Autowired private StringRedisTemplate redisTemplate;
实现
//基于 Redis 实现分布式锁 public void testLock() { //加锁 Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111"); //setIfAbsent 对应 setnx,当key不存在时可以使用setnx设置 //保证原子行Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111",3,TimeUnit.SECONDS);
if (!lock){ try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } this.testLock(); }else{ //获取锁,执行业务操作 String num = this.redisTemplate.opsForValue().get("num"); if (StringUtils.isBlank(num)){ this.redisTemplate.opsForValue().set("num","1"); return; } int i = Integer.parseInt(num); this.redisTemplate.opsForValue().set("num",String.valueOf(++i)); //释放锁 this.redisTemplate.delete("lock"); } }
//循环哪里使用while也可以,稍微改一下就行
//实现不够完整,还有部分优化空间,例如防止死锁:客户端获取到锁之后,服务器立马宕机, 解决方式:给key添加过期时间(需要保证原子性)
// 原子性 加锁和过期时间: set k v ex 3 nx nx 表示key不存在时设置 xx 表示值存在时设置
//锁的基本操作 1. 加锁: 方式一 , 使用setnx + expire 方式二,使用 set k v ex 3 nx 方式二可以加锁并保持原子性,从而防止服务器死锁

浙公网安备 33010602011771号