redis 分布式多线程细粒度锁

本文介绍如何使用Redis实现分布式锁,并提供了具体的加锁和解锁方法。通过检查锁的有效性和过期状态来确保线程安全,避免并发冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值