zoukankan      html  css  js  c++  java
  • Java基于Redis的分布式锁

    分布式锁,其实最终还是要保证锁(数据)的一致性,说到数据一致性,基于ZK,ETCD数据一致性中间件做分数是锁,才是王道。但是Redis也能满足最基本的需求。

    参考:

    https://www.cnblogs.com/technologykai/p/8658689.html

    https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_1003days.html

    @Component
    public class RedisLockManager implements Lock {
        Logger logger = LoggerFactory.getLogger(RedisLockManager.class);
    
        @Autowired
        RedisTool redisManager;
        /**
         * 请求锁的超时时间(ms)
         */
        private final long TIME_OUT = 30000;
        /**
         * 锁的有效时间(毫秒)
         */
        private long expire = 15000;
        private String key;
        private String value;
    
        private volatile boolean isLocked = false;
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    
        @Override
        public void lock() {
            //系统当前时间,毫秒
            long nowTime = System.nanoTime();
            //请求锁超时时间,毫秒
            long timeout = TIME_OUT * 1000000;
            ThreadLocalRandom random = ThreadLocalRandom.current();
            try {
                while ((System.nanoTime() - nowTime) < timeout) {
                    boolean flag = redisManager.tryGetDistributedLock(this.key, this.value, this.expire);
                    if (flag) {
                        isLocked = true;
                        //上锁成功结束请求
                        break;
                    }
                    Thread.sleep(3, random.nextInt(500));
                }
            } catch (Exception e) {
                isLocked = false;
                logger.error(e.getMessage(), e);
            }
        }
    
        @Override
        public void unlock() {
            //释放锁
            //不管请求锁是否成功,只要已经上锁,客户端都会进行释放锁的操作
            if (isLocked) {
                redisManager.releaseDistributedLock(this.key, this.value);
                this.isLocked = false;
            }
        }
    
        @Override
        public void lockInterruptibly() {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public boolean tryLock() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public boolean tryLock(long time, TimeUnit unit) {
            this.expire = unit.toMillis(time);
            this.lock();
            return this.isLocked;
        }
    
        @Override
        public Condition newCondition() {
            // TODO Auto-generated method stub
            return null;
        }
    }
    
    
    @Component
    public class RedisTool {

      @Autwire
      Jedis jedis;
    private final String LOCK_SUCCESS = "OK"; private final String SET_IF_NOT_EXIST = "NX"; private final String SET_WITH_EXPIRE_TIME = "PX"; /** * 尝试获取分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间 * @return 是否获取成功 */ public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } private final Long RELEASE_SUCCESS = 1L; /** * 释放分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @return 是否释放成功 */ public boolean releaseDistributedLock(String lockKey, String requestId) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } }
  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/fqybzhangji/p/11394962.html
Copyright © 2011-2022 走看看