zoukankan      html  css  js  c++  java
  • 分布式锁

    分布式锁-redis

    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.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     *
     */
    @Component
    public class RedisLock {
     
        Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Autowired
        private StringRedisTemplate redisTemplate;
    
        /**
         * 加锁
         * @param key
         * @param currentTimeMillis 当前时间
         * @param timeoutMillis 超时时间
         * @return
         */
        public boolean lock(String key,long currentTimeMillis, long timeoutMillis) {
            String value=  String.valueOf(currentTimeMillis+timeoutMillis);
            //这个其实就是setnx命令,只不过在java这边稍有变化,返回的是boolea
            if (redisTemplate.opsForValue().setIfAbsent(key, value)) {
                //这个过期不是原子操作,只是正常为了设置
                redisTemplate.expire(key,timeoutMillis, TimeUnit.MILLISECONDS);
                return true;
            }
     
            //避免死锁,且只让一个线程拿到锁
            String currentValue = redisTemplate.opsForValue().get(key);
            //如果锁过期了
            if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {
                //获取上一个锁的时间
                String oldValues = redisTemplate.opsForValue().getAndSet(key, value);
                /*
                   只会让一个线程拿到锁
                   如果旧的value和currentValue相等,只会有一个线程达成条件,因为第二个线程拿到的oldValue已经和currentValue不一样了
                 */
                if (!StringUtils.isEmpty(oldValues) && oldValues.equals(currentValue)) {
                    return true;
                }
            }
            return false;
        }
     
     
        /**
         * 解锁
         * @param key
    
         */
        public void unlock(String key, long currentTimeMillis, long timeoutMillis) {
            String value=  String.valueOf(currentTimeMillis+timeoutMillis);
            try {
                String currentValue = redisTemplate.opsForValue().get(key);
                if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
                    redisTemplate.opsForValue().getOperations().delete(key);
                }
            } catch (Exception e) {
                logger.error("『redis分布式锁』解锁异常,{}", e);
            }
        }
    }

     使用

  • 相关阅读:
    Apache-Shiro
    Linux下的Nginx安装
    Linux安装Redis
    Linux安装ftp组件vsftpd
    Spring笔记(二)
    Spring笔记(一)
    MySQL事务
    rocketMQ基本理解
    2018面试题小结
    v-if和v-show
  • 原文地址:https://www.cnblogs.com/xiaomaoyvtou/p/14924058.html
Copyright © 2011-2022 走看看