欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DistributedLock

程序员文章站 2022-04-19 08:22:28
...
private volatile String unlockSha1 = "";
public String lock(String lockName, long acquireTime, int lockTimeout) {
        String identifier = UuidUtil.generate32Value();
        String lock = "lock:" + lockName;
        long beginTime = System.currentTimeMillis();
        do {
            String result = jedisCluster.set(lock, identifier, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, lockTimeout);
            if (LOCK_SUCCESS.equalsIgnoreCase(result)) {
                return identifier;
            }

            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                log.error("acquireDistributedLock error:",e);
            }
        } while (System.currentTimeMillis() - beginTime < acquireTime);

        return null;
    }
//identifier 为lock返回值
public boolean releaseDistributedLock(String lockName, String identifier) {
        String lock = "lock:" + lockName;
        List<String> keys = Collections.singletonList(lock);
        List<String> args = Collections.singletonList(identifier);
        try {
            Object result = jedisCluster.evalsha(unlockSha1, keys, args);
            return RELEASE_SUCCESS.equals(result);
        } catch (JedisNoScriptException e) {
            //没有脚本缓存时,重新发送缓存
            log.info("try to store script......");
            storeScript(lock);
            Object result = jedisCluster.evalsha(unlockSha1, keys, args);
            return RELEASE_SUCCESS.equals(result);
        } catch (Exception e){
            log.error("releaseDistributedLock error:",e);
            return false;
        }
    }

private void storeScript(String lock){
        if (StringUtil.isEmpty(unlockSha1) || !jedisCluster.scriptExists(unlockSha1, lock)){
            //redis支持脚本缓存,返回哈希码,后续可以继续用来调用脚本
            unlockSha1 = jedisCluster.scriptLoad(DEL_SCRIPT, lock);
        }
    }
相关标签: lock