1 /**
2 * 获取redis的锁
3 *
4 * @param key 键
5 * @param value 值为当前毫秒数+过期时间毫秒数
6 * @return 返回true/false
7 */
8 public boolean lock(String key, String value) {
9 if (redisTemplate.opsForValue().setIfAbsent(key, value)) {
10 //加锁成功就返回true
11 return true;
12 }
13 //不加下面这个可能出现死锁情况
14 //value为当前时间+超时时间
15 //获取上一个锁的时间,并判断是否小于当前时间,小于就下一步判断,就返回true加锁成功
16 //currentValue=A 这两个线程的value都是B 其中一个线程拿到锁
17 String currentValue = (String) redisTemplate.opsForValue().get(key);
18 //如果锁过期
19 if (!StringUtils.isEmpty(currentValue)
20 && Long.parseLong(currentValue) < System.currentTimeMillis()) {
21 //存储时间要小于当前时间
22 //出现死锁的另一种情况,当多个线程进来后都没有返回true,接着往下执行,执行代码有先后,而if判断里只有一个线程才能满足条件
23 //oldValue=currentValue
24 //多个线程进来后只有其中一个线程能拿到锁(即oldValue=currentValue),其他的返回false
25 //获取上一个锁的时间
26 String oldValue = (String) redisTemplate.opsForValue().getAndSet(key, value);
27 if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
28 //上一个时间不为空,并且等于当前时间
29 return true;
30 }
31
32 }
33 return false;
34 }
35
36
37 /**
38 * redis释放锁
39 *
40 * @param key 键
41 * @param value 值
42 */
43 public void unlock(String key, String value) {
44 //执行删除可能出现异常需要捕获
45 try {
46 String currentValue = (String) redisTemplate.opsForValue().get(key);
47 if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
48 //如果不为空,就删除锁
49 redisTemplate.opsForValue().getOperations().delete(key);
50 }
51 } catch (Exception e) {
52 log.error("[redis分布式锁] 解锁", e);
53 }
54 }