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; } }
  • 相关阅读:
    Jenkins入门教程(3)
    Jenkins入门教程(2)
    Jenkins入门教程(1)
    Tomcat与Weblogic
    fidder教程
    postman教程(3)- 用Postman生成Request代码
    postman教程(2)— 在test suite中运行test case
    postman教程(1)
    unix环境高级编程——文件和目录
    unix环境高级编程——文件IO
  • 原文地址:https://www.cnblogs.com/fqybzhangji/p/11394962.html
Copyright © 2011-2022 走看看