Redis分布式锁

来源:11-6 实现分布式锁-Redis

phoenix_wsf

2023-12-18

图片描述
redis分布式锁,注解测试锁能通过,但是手动锁测试报错,请问这是什么情况

图片描述
RedisLockConfig

package com.imooc.pan.lock.redis;

import com.imooc.pan.lock.core.LockConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.integration.support.locks.LockRegistry;

/**
 *
 *<p>基于Redis使用分布式锁</p>
 * 该方案集成Spring-data-redis,配置项也是用原来的配置,不重复造轮子
 *
 * @project r-pan
 * @description
 * @author Phoenix
 * @Date 2023/12/18 21:26:02
 * @version 1.0
 **/
@SpringBootConfiguration
@Slf4j
public class RedisLockConfig
{
    @Bean
    public LockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory)
    {
        RedisLockRegistry lockRegistry = new RedisLockRegistry(redisConnectionFactory, LockConstants.R_PAN_LOCK);
        log.info("初始化RedisLockRegistry 成功!");
        return lockRegistry;
    }
}

LockTester.java

package com.imooc.pan.lock.redis.test.instance;

import com.imooc.pan.lock.core.annotation.Lock;
import org.springframework.stereotype.Component;

/**
 *
 *<p>des</p>
 *
 * @project r-pan
 * @description
 * @author Phoenix
 * @Date 2023/12/17 16:25:18
 * @version 1.0
 **/
@Component
public class LockTester
{
    @Lock(name = "testLock", keys = "#name", expireSecond = 10L)
    public String testLock(String name)
    {
        System.out.println(Thread.currentThread().getName() + "get the lock." + name);
        System.out.println(Thread.currentThread().getName() + "release the lock." + name);
        return "hello".concat(name);
    }
}

testLockRegistry.java

package com.imooc.pan.lock.redis.test;

import com.imooc.pan.lock.core.LockConstants;
import com.imooc.pan.lock.redis.test.instance.LockTester;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.integration.support.locks.LockRegistry;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 *
 *<p></p>
 *
 * @project r-pan
 * @description
 * @author Phoenix
 * @Date 2023/12/17 16:28:28
 * @version 1.0
 **/
@SpringBootTest(classes = RedisLockTest.class)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootApplication(scanBasePackages = "com.imooc.pan.lock")
public class RedisLockTest
{

    @Resource
    private LockRegistry lockRegistry;

    @Resource
    private LockTester lockTester;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     *<p>测试手动获取锁</p>
     *
     * @return void
     * @author Phoenix
     * @since 2023/12/17 16:36
     */
    @Test
    public void testLockRegistry() throws InterruptedException
    {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++)
        {
            threadPoolTaskExecutor.execute(() ->
            {
                Lock lock = lockRegistry.obtain(LockConstants.R_PAN_LOCK);
                boolean lockResult = false;
                try
                {
                    lockResult = lock.tryLock(60L, TimeUnit.SECONDS);
                    if (lockResult)
                    {
                        System.out.println(Thread.currentThread().getName() + "get the lock.");
                    }
                } catch (InterruptedException e)
                {
                    throw new RuntimeException(e);
                } finally
                {
                    if (lockResult)
                    {
                        lock.unlock();
                        System.out.println(Thread.currentThread().getName() + "release the lock.");
                    }
                }
            });
            countDownLatch.countDown();
        }
        countDownLatch.await();
    }

    /**
     *<p>测试锁注解</p>
     *
     *
     * @return void
     * @author Phoenix
     * @since 2023/12/17 16:38
     */
    @Test
    public void testLockTester() throws InterruptedException
    {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++)
        {
            threadPoolTaskExecutor.execute(() ->
            {
                lockTester.testLock("imooc");
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
    }
}

application.properties

spring.redis.database=1
spring.redis.host=192.168.75.133
写回答

1回答

RubinChu

2023-12-19

同学贴一下源码,以及当时的环境信息哈,比如redis是不是本地安装,是否改动过测试用例等等

0
2
RubinChu
回复
phoenix_wsf
这个看代码之类的没有问题 我看你贴的图里面测试用例是通过的状态 感觉就是环境的问题 同学可以在项目中集成 写一个测试接口试一下哈
2023-12-19
共2条回复

SpringBoot+Vue3+Element Plus打造私人分布式存储系统

SpringBoot+Vue3+Element Plus 仿百度网盘实战

274 学习 · 346 问题

查看课程