Java 实现分布式锁(Redisson)

在分布式系统中,多个服务可能需要访问共享资源,而为了保证资源的一致性和完整性,必须使用分布式锁。分布式锁用于控制不同机器上的应用程序访问共享资源的时序问题。本文将通过 Java 使用 Redisson 来实现一个分布式锁。

代码实现:

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.Redisson;

import java.util.concurrent.TimeUnit;

public class DistributedLockExample {

    private static RedissonClient redissonClient;

    // 初始化 Redisson 客户端
    public static void initRedisson() {
        Config config = new Config();
        // 使用 Redis 服务器的 IP 和端口
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        redissonClient = Redisson.create(config);
    }

    // 锁定共享资源
    public static void acquireLock(String lockName) {
        // 创建分布式锁
        RLock lock = redissonClient.getLock(lockName);

        try {
            // 尝试获得锁,最多等待 10 秒,锁定后 30 秒自动释放
            if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
                System.out.println(Thread.currentThread().getName() + " 获得锁 " + lockName);
                
                // 模拟共享资源的操作
                simulateSharedResourceOperation();
            } else {
                System.out.println(Thread.currentThread().getName() + " 获取锁失败,正在重试...");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + " 释放锁 " + lockName);
            }
        }
    }

    // 模拟操作共享资源
    private static void simulateSharedResourceOperation() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " 正在操作共享资源...");
        // 模拟一些耗时操作,例如数据库操作、文件操作等
        Thread.sleep(5000);
    }

    // 关闭 Redisson 客户端
    public static void shutdownRedisson() {
        if (redissonClient != null) {
            redissonClient.shutdown();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 初始化 Redisson 客户端
        initRedisson();

        // 使用多个线程模拟不同服务
        Thread thread1 = new Thread(() -> acquireLock("sharedLock"));
        Thread thread2 = new Thread(() -> acquireLock("sharedLock"));
        Thread thread3 = new Thread(() -> acquireLock("sharedLock"));

        // 启动线程
        thread1.start();
        thread2.start();
        thread3.start();

        // 等待线程执行完成
        thread1.join();
        thread2.join();
        thread3.join();

        // 关闭 Redisson 客户端
        shutdownRedisson();
    }
}

代码解析:

  1. RedissonClient 初始化

    • initRedisson 方法中,我们通过 Redisson.create 创建了一个 RedissonClient 实例,并连接到 Redis 服务器。此代码假设 Redis 服务器地址为 redis://127.0.0.1:6379
  2. 获取和释放分布式锁

    • 使用 redissonClient.getLock(lockName) 创建一个基于 Redis 的分布式锁(RLock)。
    • acquireLock 方法中,tryLock 方法尝试获取锁。tryLock 的第一个参数是最大等待时间,第二个参数是锁的超时释放时间,单位是秒。
    • 获取锁后,模拟了对共享资源的操作,模拟的操作持续 5 秒。
    • 无论是否获取到锁,程序都会在最后释放锁。
  3. 多线程模拟

    • main 方法中,我们创建了三个线程来模拟不同的服务同时请求同一个共享资源的情况。每个线程都调用 acquireLock 方法来尝试获取分布式锁。
  4. 锁释放

    • unlock() 方法在操作完成后释放锁。需要注意的是,只有持有锁的线程才能释放该锁。

使用说明:

  1. 环境要求

    • 本代码依赖于 Redis 和 Redisson。你需要安装并运行 Redis 服务器,并将 Redisson 库添加到你的项目中(通过 Maven 或 Gradle)。
    • Maven 依赖:
      <dependency>
          <groupId>org.redisson</groupId>
          <artifactId>redisson</artifactId>
          <version>3.16.3</version>
      </dependency>
      
  2. 功能描述

    • 该示例展示了如何通过 Redisson 实现分布式锁,确保不同实例(线程)在访问共享资源时能够按序访问,避免出现数据竞争等问题。
    • 我们在 Redis 中使用一个分布式锁,保证多个不同的服务实例在分布式环境中能正确地竞争共享资源。
  3. 如何使用

    • 初始化 Redisson 客户端时,可以更改 Redis 的连接配置,支持集群、主从等多种 Redis 部署方式。
    • 可以调整锁的等待时间、过期时间和锁的名称来满足不同的业务需求。
    • 本示例模拟了三种线程请求同一个锁,并展示了分布式锁的竞争与释放。
  4. 场景应用

    • 本例适用于需要多线程或多服务实例竞争同一资源的场景,例如:
      • 分布式数据库操作:确保多个应用不会同时插入或修改相同的记录。
      • 分布式任务调度:确保只有一个服务实例执行定时任务。
      • 分布式计数器:在多个实例间协调访问和更新计数器。

总结:

通过 Java 和 Redisson 实现的分布式锁,可以有效解决分布式系统中多实例间对共享资源的访问问题。Redisson 提供了简洁的 API,支持 Redis 环境下的分布式锁、信号量、队列等多种同步工具,能够简化开发者的分布式系统编程工作。在大规模、高并发的系统中,使用分布式锁能有效保证数据的一致性和完整性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值