• 分布式锁


    分布式锁-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);
            }
        }
    }

     使用

  • 相关阅读:
    Schema和数据类型优化?
    语雀发布博客园
    为知笔记文章目录
    码云搭建博客
    springboot的过滤器、监听器、拦截器
    springboot常用注解
    springboot使用小技巧合集
    springboot整合swagger2
    强制卸载win软件
    xshell下载和优化配置
  • 原文地址:https://www.cnblogs.com/xiaomaoyvtou/p/14924058.html
Copyright © 2020-2023  润新知