RedisDistributedLock

Redis实现的分布式锁,适用于对公共资源争抢更新加锁和解锁

@Slf4j
@Component("redisDistributedLock")
public class RedisDistributedLock {
    @Autowired
    private JedisClient jedisClient;

    public static final String BEAN_NAME = "redisDistributedLock";

    private static final int DEFAULT_ACQUIRE_MSECS = 100;
    /**
     * 锁等待时间,防止线程饥饿
     */
    private static final int TIMEOUT_MSECS = 5 * 1000;

    /**
     * Redis key
     */
    private String lockKey = "key_distributed_lock";

    /**
     * 过期时间,毫秒
     */
    private int expiredMsecs = 60 * 1000;

    private volatile boolean locked = false;


    /**
     * 上锁
     *
     * @return
     * @throws InterruptedException
     */
    public synchronized boolean acquireLock() throws InterruptedException {
        log.info(">>>>>>>>>> the name of distributed lock is {}", lockKey);
        int timeout = TIMEOUT_MSECS;
        while (timeout >= 0) {
            long expires = System.currentTimeMillis() + expiredMsecs + 1;
            String expiresStr = String.valueOf(expires);
            log.info(">>>>>>>>>>the content of distributed lock is {}", expiresStr);
            if (jedisClient.setnx(lockKey, expiresStr) == 1) {
                log.info(">>>>>>>>>> acquire the distributed lock({}) immediately", lockKey);
                locked = true;
                return true;
            }

            String currValueStr = jedisClient.get(lockKey);
            if (currValueStr != null && Long.parseLong(currValueStr) < System.currentTimeMillis()) {
                String preValueStr = jedisClient.getSet(lockKey, expiresStr);
                if (preValueStr != null && preValueStr.equals(currValueStr)) {
                    log.info(">>>>>>>>>> acquire the distributed lock({}) finally", lockKey);
                    locked = true;
                    return true;
                }
            }
            timeout -= DEFAULT_ACQUIRE_MSECS;
            Thread.sleep((long) (Math.random() * DEFAULT_ACQUIRE_MSECS));
        }
        return false;
    }

    /**
     * 解锁
     */
    public synchronized void releaseLock() {
        if (locked) {
            jedisClient.del(this.lockKey);
            locked = false;
            log.info("<<<<<<<<<< release the distributed lock({}) successfully", lockKey);
        }
    }

    public String getLockKey() {
        return lockKey;
    }

    public void setLockKey(String lockKey) {
        this.lockKey = lockKey;
    }

    public int getExpiredMsecs() {
        return expiredMsecs;
    }

    public void setExpiredMsecs(int expiredMsecs) {
        this.expiredMsecs = expiredMsecs;
    }
}

public void test(){
        final String lockKey = Constants.APP_KEY.concat(Constants.ACT_SIGN_UP_KEY).concat(id);
        RedisDistributedLock redisDistributedLock = SpringContextUtils.getBean(RedisDistributedLock.BEAN_NAME);
        redisDistributedLock.setLockKey(lockKey);
        try {
            if (redisDistributedLock.acquireLock()) {
                //TODO
            }
        } catch (InterruptedException e) {
            log.error("异常,e=" + e.getMessage());
        } finally {
            redisDistributedLock.releaseLock();
        }

    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值