redis分布式锁

什么是分布式锁,为什么需要分布式锁,这些问题在这里我就重复了,相关资料很多就复述了!

官方文档:https://redis.io/topics/distlock

参考博客:http://www.cnblogs.com/linjiqin/p/8003838.html

首先,我们要知道分布式锁必须具备的特性:

  1. 互斥性(安全):再多线程环境下,必须只能有某一个线程持有锁
  2. 避免死锁:在规定时间内,持有锁的线程必须释放锁,如果该线程没有主动释放则自动释放锁
  3. 可用性:当出现单点故障时,可以保证锁正常的设置和释放
  4. 除设置锁客户端之外,其他客户端不能释放锁

引入依赖:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>x.x.x</version>
</dependency>

 

使用redis设置锁:

public class RLock{

    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";

    /**
     * 设置分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param clientId 客户端标识
     * @param expireTime 超期时间
     * @return 是否设置成功
     */
    public static boolean setLock(Jedis jedis, String lockKey, String clientId, int expireTime) {

        String result = jedis.set(lockKey, clientId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

        if (LOCK_SUCCESS.equals(result)) {
            return true;
        }
        return false;

    }

}

释放锁:

public class Rlock {

    private static final Long RELEASE_SUCCESS = 1L;

    /**
     * 释放分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param clientId 客户端标识
     * @return 是否释放成功
     */
    public static boolean releaseLock(Jedis jedis, String lockKey, String clientId) {

        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(clientId));

        if (RELEASE_SUCCESS.equals(result)) {
            return true;
        }
        return false;

    }

}

 

posted @ 2019-03-20 17:05  一天学点  阅读(302)  评论(0编辑  收藏  举报