分布式锁

package com.msxf.eyas.common.lock;

/**
 * 分布式锁
 *
 */
public interface DistributedLock {
    /**
     * 加锁, 立即返回
     * @return true 成功
     */
    boolean lock();

    /**
     * 加锁
     *
     * @param waitTimeoutMillis 等待时间,毫秒
     * @return true 成功
     */
    boolean lock(long waitTimeoutMillis);

    /**
     * 解锁
     */
    void unLock();
}
import org.springframework.util.Assert;
import redis.clients.jedis.JedisCluster;

/**
 * 
 */
public class RedisDistributedLock implements DistributedLock {

    private JedisCluster jedisCluster;

    /**
     * 加锁key
     */
    private String key;
    /**
     * 锁持有时间
     */
    private long holdTimeMillis;
    /**
     * 当前锁失效时间
     */
    private long expiresAt = 0;

    public RedisDistributedLock(JedisCluster jedisCluster, String key, long holdTimeMillis) {
        Assert.isTrue(holdTimeMillis > 0, "Argument holdTimeMillis must > 0.");

        this.jedisCluster = jedisCluster;
        this.key = key;
        this.holdTimeMillis = holdTimeMillis;
    }

    @Override
    public boolean lock() {
        return this.lock(0);
    }

    @Override
    public boolean lock(long waitTimeoutMillis) {
        while (waitTimeoutMillis >= 0) {
            long expiresAt = System.currentTimeMillis() + this.holdTimeMillis + 1;
            if (this.jedisCluster.setnx(this.key, String.valueOf(expiresAt)) == 1) {
                this.expiresAt = expiresAt;
                return true;
            }

            String expectedExpiryTime = this.jedisCluster.get(this.key);
            if (expectedExpiryTime != null && System.currentTimeMillis() > Long.parseLong(expectedExpiryTime)) {
                String actualExpiryTime = this.jedisCluster.getSet(this.key, String.valueOf(expiresAt));
                // 设置逾期时间, 并和前一次获取相等才代表当前加锁成功
                if (actualExpiryTime != null && expectedExpiryTime.equals(actualExpiryTime)) {
                    this.expiresAt = expiresAt;
                    return true;
                }
            }

            waitTimeoutMillis -= 100;
            if (waitTimeoutMillis > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // do nothing.
                }
            }
        }

        return false;
    }

    @Override
    public void unLock() {
        String actualExpiryTime = this.jedisCluster.get(this.key);
        // 逾期时间相等才删除
        if (actualExpiryTime != null && actualExpiryTime.equals(this.expiresAt)) {
            this.jedisCluster.del(key);
            this.expiresAt = 0;
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值