Просмотр исходного кода

[分布式锁][修改]

release_toaliyun_real
Stormeye Wu 6 лет назад
Родитель
Сommit
991c87271d
1 измененных файлов: 8 добавлений и 3 удалений
  1. +8
    -3
      mallinkService/src/main/java/com/iformall/utils/RedisLock.java

+ 8
- 3
mallinkService/src/main/java/com/iformall/utils/RedisLock.java Просмотреть файл

@@ -4,9 +4,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
* RedisLock
* User: Stormeye
@@ -29,17 +32,19 @@ public class RedisLock {
* @return
*/
public boolean lock(String key,String value){
if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){//对应setnx命令
ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
if(operations.setIfAbsent(key,value)){//对应setnx命令
operations.set(key, value, 1, TimeUnit.SECONDS);
//可以成功设置,也就是key不存在
return true;
}

//判断锁超时 - 防止原来的操作异常,没有运行解锁操作 防止死锁
String currentValue = stringRedisTemplate.opsForValue().get(key);
String currentValue = operations.get(key);
//如果锁过期
if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){//currentValue不为空且小于当前时间
//获取上一个锁的时间value
String oldValue =stringRedisTemplate.opsForValue().getAndSet(key,value);//对应getset,如果key存在
String oldValue =operations.getAndSet(key,value);//对应getset,如果key存在

//假设两个线程同时进来,key被占用了。获取的值currentValue=A(get取的旧的值肯定是一样的),两个线程的value都是B,key都是K.锁时间已经过期了。
//而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的value已经变成了B。只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。


Загрузка…
Отмена
Сохранить