redis 分布式多线程细粒度锁

@Autowired
private StringRedisTemplate redisTemplate;

加锁

/**
 *
 * @param key
 * @param value 一般用 当前时间+超时时间
 * @return
 */
public boolean lock(String key,String value){

    if(redisTemplate.opsForValue().setIfAbsent(key,value)){
        //没有线程获得这个key的锁
        return true;
    }

    // 即使锁被占用,再判断锁是否过期
    String currentValue = redisTemplate.opsForValue().get(key);
    if(!StringUtils.isEmpty(currentValue) &&
            Long.parseLong(currentValue) < System.currentTimeMillis()){
        // 锁过期,再判断是否有两个线程都走到了这里,还是有锁的原子性问题.

        //利用了Redis操作的原子性。该方法是原子操作。所以后一个线程执行该方法是在前一个线程已经设置好value并且返回给oldValue之后
        // 这样第一个进来的线程是可以返回true。后面的都不可以。
        // 所以理论上value值是不能有重复的。
        String oldValue = redisTemplate.opsForValue().getAndSet(key,value);
        if(!StringUtils.isEmpty(oldValue) && oldValue.equals(value)){
            return true;
        }
    }
    return false;
}

解锁

public void unlock(String key,String value){
    String currentValue = redisTemplate.opsForValue().get(key);
    if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value)){
        redisTemplate.opsForValue().getOperations().delete(key);
    }
}

你可能感兴趣的:(redis)