redis setnx分布式锁

在 Redis 里,所谓 SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果!

以下的方法主要用于一个应用部署到多个服务器下定时任务只有一个服务器执行

 

/**
 * 判断定时任务是否可以执行
 * 如果key已经存在,那么返回0,不覆盖
 * 如果key不存在,则设置一个新value,返回1
 * @return
 */
public synchronized boolean canUseTaskFlag(String redisKey,Long timeout) {
    String expiresStrTime = String.valueOf(System.currentTimeMillis() + timeout); //锁到期时间
    if (redisClient.setnx(redisKey, expiresStrTime) == 1) {
        log.info(" redisKey =  "+ redisKey +" and expiresStrTime = "+expiresStrTime+"   
        and run flag is true");
        return true;
    }
    String currentValueStr = redisClient.get(redisKey); //redis里的时间
    if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
        //判断是否为空,不为空的情况下,如果被其他线程设置了值,则第二个条件判断是过不去的
        // lock is expired
        String oldValueStr = redisClient.getsetValue(redisKey, expiresStrTime);
        //获取上一个锁到期时间,并设置现在的锁到期时间,
        //只有一个线程才能获取上一个线上的设置时间,因为jedis.getSet是同步的
        if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
            //如过这个时候,多个线程恰好都到了这里,但是只有一个线程的设置值和当前值相同,他才有权利获取锁
            // lock acquired
            log.info(" redisKey =  "+ redisKey +" and expiresStrTime = "+expiresStrTime+"   
                and run flag is true");
            return true;
        }
    }
    log.info(" redisKey =  "+ redisKey +" and expiresStrTime = "+expiresStrTime+"   
    and run flag is false");
    return false;
}

 

使用DEMO

public void testUse() {
    try {
        //为了防止redis同一时间被调用
        Thread.sleep(700);
        //如果key已经存在,那么返回0,不覆盖
        //如果key不存在,则设置一个新value,返回1
        boolean flag = canUseTaskFlag("test_key",10L*60*1000L - 1L);//每10分钟执行一次
        if (flag){
            //可以执行
        }
        redisClient.delKey("test_key");
    }  catch (Exception e) {
        redisClient.delKey("test_key");
        e.printStackTrace();
    }
}

转载于:https://my.oschina.net/u/3239611/blog/997805

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值