Redis分布式锁实例

Posted 一个笨蛋的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis分布式锁实例相关的知识,希望对你有一定的参考价值。

maven依赖

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

代码实现

package com.zhi.demo;

import java.util.Collections;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.params.SetParams;

/**
 * Redis分布式锁
 *
 * @date 2019年03月05日17:20:05
 *
 */
public class RedisLock {
    private static JedisPool jedisPool;
    /**
     * 加锁成功标示
     */
    private static final String LOCK_SUCCESS = "OK";
    /**
     * 解锁成功标示
     */
    private static final Long RELEASE_SUCCESS = 1L;

    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(5);
        config.setTestOnBorrow(false);

        jedisPool = new JedisPool(config, "192.168.153.137", 6379);
    }

    /**
     * 申请锁
     * 
     * @param key       锁名
     * @param requestId 请求ID,一般用UUID(用于记录谁申请的锁)
     * @return 是否成功
     * 
     */
    public static boolean lock(String key, String requestId) {
        try (Jedis jedis = jedisPool.getResource();) {
            SetParams params = new SetParams();
            params.ex(100); // 设置超时时间
            params.nx(); // 若锁不存在才进行写操作
            String back = jedis.set(key, requestId, params);
            return LOCK_SUCCESS.equals(back);
        }
    }

    /**
     * 解锁,判断requestId的一致性和删除锁必须放在一个请求中,防止时间差引起错误
     * 
     * @param jedis
     * @param key       锁名
     * @param requestId 请求ID
     * @return 是否解锁成功
     * 
     */
    public static boolean unlock(String key, String requestId) {
        try (Jedis jedis = jedisPool.getResource();) {
            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(key), Collections.singletonList(requestId));
            return RELEASE_SUCCESS.equals(result);
        }
    }

    public static void main(String[] args) {
        if (RedisLock.lock("redis", "1")) {
            System.out.println("申请锁成功");
            if (RedisLock.lock("redis", "2")) {
                System.out.println("再次申请锁成功");
            } else {
                System.out.println("再次申请锁失败");
            }
            if (RedisLock.unlock("redis", "1")) {
                System.out.println("解锁成功");
            } else {
                System.out.println("解锁失败");
            }
        } else {
            System.out.println("申请锁失败");
        }
        jedisPool.close();
    }
}

 

有兴趣的同学可以参考:https://www.cnblogs.com/linjiqin/p/8003838.html,这个讲解比较清楚。

以上是关于Redis分布式锁实例的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

单实例redis分布式锁的简单实现

Redis分布式锁实例

编程实践分布式锁的实现代码

redis分布式锁实践

redis分布式锁-自动超时锁