Redis 分布式锁教程

Redis 分布式锁教程

简介

在分布式系统中,多个进程可能会尝试同时访问共享资源,这会导致数据不一致或者竞争条件。分布式锁是一种用于控制对共享资源访问的机制。Redis 是一个流行的内存数据存储系统,可以用来实现分布式锁。

本文将介绍如何使用 Redis 实现分布式锁,并提供一个简单的 Java 代码示例。

环境准备

在开始之前,请确保你的开发环境已经安装了以下组件:

  • Java Development Kit (JDK) 8 或更高版本
  • Maven 或其他构建工具
  • Redis 服务器

引入依赖

首先,在你的 pom.xml 文件中引入 Jedis(一个 Redis 的 Java 客户端)的依赖:

xml 复制代码
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.1.3</version>
</dependency>

示例代码

下面是一个简单的 Java 代码示例,展示如何使用 Redis 实现分布式锁。

RedisLock.java

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

public class RedisLock {

    private Jedis jedis;
    private String lockKey;
    private int lockExpireTime;

    public RedisLock(Jedis jedis, String lockKey, int lockExpireTime) {
        this.jedis = jedis;
        this.lockKey = lockKey;
        this.lockExpireTime = lockExpireTime;
    }

    public boolean acquireLock(String uniqueId) {
        // 使用 SETNX 命令设置锁
        String result = jedis.set(lockKey, uniqueId, new SetParams().nx().px(lockExpireTime));
        return "OK".equals(result);
    }

    public boolean releaseLock(String uniqueId) {
        // 使用 Lua 脚本确保释放锁的原子性
        String luaScript =
                "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) " +
                "else " +
                "return 0 " +
                "end";
        Object result = jedis.eval(luaScript, 1, lockKey, uniqueId);
        return result != null && (Long) result > 0;
    }
}

Main.java

java 复制代码
import redis.clients.jedis.Jedis;
import java.util.UUID;

public class Main {

    public static void main(String[] args) {

        for (int i = 0; i < 3; i++) {
            new Thread(new RedisLocalTest()).start();
        }
    }

    static class RedisLocalTest implements Runnable {

        String lockKey = "myLock";
        int lockExpireTime = 10000; // 锁过期时间为 10 秒

        public void run() {
            Jedis jedis = new Jedis("localhost", 6379);
            //jedis.auth("123456"); // redis 配置密码需要设置
            RedisLock redisLock = new RedisLock(jedis, lockKey, lockExpireTime);
            String uniqueId = UUID.randomUUID().toString();
            String threadName = Thread.currentThread().getName();
            if (redisLock.acquireLock(uniqueId)) {
                System.out.println(threadName + " 获取到锁!");
                // 在这里执行你的业务逻辑
                try {
                    Thread.sleep(5000); // 模拟业务处理时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (redisLock.releaseLock(uniqueId)) {
                        System.out.println(threadName + " 锁已释放!");
                    } else {
                        System.out.println(threadName + " 释放锁失败!");
                    }
                }
            } else {
                System.err.println(threadName + " 未能获取到锁!");
            }

            jedis.close();
        }
    }
}

运行示例

  1. 启动 Redis 服务器。
  2. 编译并运行 Main 类。

你应该会看到类似如下的输出:

复制代码
Thread-0 获取到锁!
Thread-2 未能获取到锁!
Thread-1 未能获取到锁!
Thread-0 锁已释放!

结论

本文介绍了如何使用 Redis 实现分布式锁,并提供了一个简单的 Java 示例代码。通过这种方式,你可以确保在分布式系统中多个进程对共享资源的访问是有序且安全的。希望这篇文章对你有所帮助!

如果你有任何问题或改进建议,欢迎讨论!

相关推荐
apihz4 分钟前
域名WHOIS信息查询免费API使用指南
android·开发语言·数据库·网络协议·tcp/ip
gwcgwcjava10 分钟前
[时序数据库-iotdb]时序数据库iotdb的安装部署
数据库·时序数据库·iotdb
remCoding17 分钟前
Java全栈面试实录:从电商场景到AIGC的深度技术考察
spring boot·redis·spring cloud·ai·kafka·aigc·java面试
SHUIPING_YANG24 分钟前
根据用户id自动切换表查询
java·服务器·数据库
爱吃烤鸡翅的酸菜鱼36 分钟前
IDEA高效开发:Database Navigator插件安装与核心使用指南
java·开发语言·数据库·编辑器·intellij-idea·database
超奇电子41 分钟前
阿里云OSS预签名URL上传与临时凭证上传的技术对比分析
数据库·阿里云·云计算
神仙别闹1 小时前
基于C#+SQL Server实现(Web)学生选课管理系统
前端·数据库·c#
m0_653031361 小时前
PostgreSQL技术大讲堂 - 第97讲:PG数据库编码和区域(locale)答疑解惑
数据库·postgresql
会编程的林俊杰1 小时前
MySQL中的锁有哪些
数据库·mysql
cts6181 小时前
Milvus分布式数据库工作职责
数据库·分布式·milvus