• redis 分布式锁的简单使用


    RedisLock——让 Redis 分布式锁变得简单

    lisence jdk

    1. 项目介绍

    该项目主要简化了使用 redis 分布式事务所的操作,实现傻瓜式加锁,释放锁的操作,并优雅的实现了等待锁释放的操作。等待锁释放的过程主要是使用了redis的监听功能,所以在使用该项目前,要确保redis已经开启了key事件监听,即“Ex”。

    • 如何查看 redis 是否已经开启了监听功能?
      登录 redis 后,使用命令 config get notify-keyspace-events 进行查看

    github地址:https://github.com/chimmhuang/redislock
    码云地址:https://gitee.com/chimmhuang/redislock
    欢迎 Start、Fork~

    2. 快速使用

    2.1 引入 maven 坐标

    <dependency>
        <groupId>com.github.chimmhuang</groupId>
        <artifactId>redislock</artifactId>
        <version>1.0.2</version>
    </dependency>
    

    2.2 注册 RedisLock

    • 方式一(推荐): 在项目的启动类上添加包扫描的路径
    @ComponentScan(basePackages = "com.github.chimmhuang.redislock")
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    • 方式二:手动注册相关的 bean
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            return container;
        }
    
        @Bean
        public RedisListener redisListener(RedisMessageListenerContainer redisMessageListenerContainer) {
            return new RedisListener(redisMessageListenerContainer);
        }
    
        @Bean
        public RedisLock redisLock(RedisTemplate redisTemplate) {
            return new RedisLock(redisTemplate);
        }
    }
    

    2.3 使用

    1. 注入 redisLock
    2. 使用 redisLock.lock(key,expire) 进行加锁
    3. 使用 redisLock.unlock(key) 进行解锁

    以下提供一个单元测试的案例(火车站卖票的案例)

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class RedisListenerTest {
    
        @Autowired
        private RedisLock redisLock;
    
        /** 100张票 */
        private static Integer count = 100;
    
        @Test
        public void ticketTest() throws Exception {
            TicketRunnable tr = new TicketRunnable();
            // 四个线程对应四个窗口
            Thread t1 = new Thread(tr,"窗口A");
            Thread t2 = new Thread(tr,"窗口B");
            Thread t3 = new Thread(tr,"窗口C");
            Thread t4 = new Thread(tr,"窗口D");
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
    
            Thread.currentThread().join();
    
        }
    
        public class TicketRunnable implements Runnable {
            @Override
            public void run() {
                while (count > 0) {
                    redisLock.lock("ticketLock", 3L);
                    if (count > 0) {
                        System.out.println(Thread.currentThread().getName() + "售出第" + (count--) + "张火车票");
                    }
                    redisLock.unlock("ticketLock");
    
                    try {
                        Thread.sleep(2000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    3. 参与贡献

    非常欢迎你的加入!提一个 Issue 或者提交一个 Pull Request。

    目前仅仅是实现了加锁解锁的简单过程,还有其他操作有待完善和测试,如:

    -[ ] 在 redis 的集群环境中,需要监听每一个 redis 的 key 事件
    -[ ] 在 redis 的主备模式下,可能会存在主备 redis 切换的期间,数据(key)未同步过去问题

    4. 联系作者

    QQ(Wechat) : 905369866
    Email : chimmhuang@163.com

    5. 开源协议

    MIT © Chimm Huang

  • 相关阅读:
    innerHTML和outerHTML的区别
    递归,汉诺塔
    js 中的 Math.ceil() Math.floor Math.round()
    JS中的异常exception
    CSS样式中visited,hover,active , focus这四个分别表示什么意思?
    用户在设置密码时,提醒请输入半角字符(vue+element+valid)
    设置用户密码时,将全角转换为半角
    后台返回对象数组,对象属性相同时,只取一个对象
    远程链接mongoDB robomongo
    mongodb 入坑
  • 原文地址:https://www.cnblogs.com/chimmhuang/p/13053578.html
Copyright © 2020-2023  润新知