分布式请求
模拟场景:多线程,高并发
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.UUID;
public class Demo {
@Autowired
StringRedisTemplate stringRedisTemplate;
private void getRedisLock(){
String uuid = UUID.randomUUID().toString();
//保持原子性,设置锁的同时,设置过过期时间,
Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);
System.out.println(lock);
if (lock) {
System.out.println("获取分布式锁成功...");
try {
//业务代码
} finally {
// 获取对比值和对比成功删除锁也是要同步的、原子的执行 参照官方使用lua脚本解锁
String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
Long lock1 = stringRedisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class),
Arrays.asList("lock"), uuid);
}
} else {
// 加锁失败休眠一段时间...重试获取锁
System.out.println("获取分布式锁失败...等待重试");
// 重试的频率太快会导致内存溢出
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
//重复尝试
getRedisLock();
}
}
}