zoukankan      html  css  js  c++  java
  • 使用redis做分布式锁

    1、使用setnx命令。先看下官方文档http://redis.cn/commands/setnx.html

    2、使用getset命令。先获取,再set

    实现案例:

      

     * create 2018-12-03 16:22
    * <p>
    * desc
    **/
    @Component
    @Slf4j
    public class RedisLock {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public boolean lock(String key,String timeout){
    //在StringRedisTemplate中,setIfAbsent = setnx
    //timeout = 当前时间 + 超时时间
    if(redisTemplate.opsForValue().setIfAbsent(key,timeout)){
    //能成功set则证明拿到了锁
    return true;
    }

    //假如key已经存在

    String currentValue = redisTemplate.opsForValue().get(key);//获取当前key的值

    /**
    * 此处为了防止死锁
    */

    //如果锁过期
    if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){
    //获取上一个锁的时间
    String oldValue = redisTemplate.opsForValue().getAndSet(key,timeout);

    if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)){
    return true;
    }
    }
    return false;
    }

    //解锁
    public void unlock (String key,String value){
    String currentValue = redisTemplate.opsForValue().get(key);
    try{
    if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value)){
    redisTemplate.opsForValue().getOperations().delete(key);
    }
    }catch (Exception e){
    log.error("解锁异常,{}",e);
    }
    }
    }


    然后在需要加锁的逻辑上,引用这个锁方法即可
    @Autowired
    RedisLock redisLock ;


    xxxx //业务逻辑

    String time = System.currentTimeMillis()+10*1000;//超时10秒钟

    if(!redisLock.lock(key,time) ){
      //假如没锁上
      //抛出异常
    }

    xxxxx //业务逻辑

    //解锁
    redisLock.unlock(key,time);


    其他方案可参考:
    http://www.cnblogs.com/seesun2012/p/9214653.html


  • 相关阅读:
    POJ 2502 Subway(最短路径)
    HDU 1430 魔板
    HDU 1043 POJ 1077 八数码问题
    POJ 2576 Tug of War 随机算法(非正规解法)
    什么是COM
    6.0的版本的 tc,不支持大漠对象做数组吗?
    Q键连发。按住Q键则连发。松开则停止1。
    Q键连发。按住Q键 则连发。松开则停止2。
    特殊符号。
    僵尸_另类的生命体。
  • 原文地址:https://www.cnblogs.com/memoa/p/10059457.html
Copyright © 2011-2022 走看看