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

posted @ 2020-06-06 09:38  吃茫茫  阅读(752)  评论(0编辑  收藏  举报