redis 分布式锁的简单使用
RedisLock——让 Redis 分布式锁变得简单
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 使用
- 注入
redisLock - 使用
redisLock.lock(key,expire)进行加锁 - 使用
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
redis 分布式锁的简单使用的更多相关文章
- Redis分布式锁实现简单秒杀功能
这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...
- 单实例redis分布式锁的简单实现
redis分布式锁的基本功能包括, 同一刻只能有一个人占有锁, 当锁被其他人占用时, 获取者可以等待他人释放锁, 此外锁本身必须能超时自动释放. 直接上java代码, 如下: package com. ...
- 自己写了个简单的redis分布式锁【我】
自己写了个简单的redis分布式锁 [注意:此锁需要在每次使用前都创建对象,也就是要在线程内每次都创建对象后使用] package redis; import java.util.Collection ...
- .NetCore使用Redis,StackExchange.Redis队列,发布与订阅,分布式锁的简单使用
环境:之前一直是使用serverStack.Redis的客服端,今天来使用一下StackExchange.Redis(个人感觉更加的人性化一些,也是免费的,性能也不会差太多),版本为StackExch ...
- 利用redis分布式锁的功能来实现定时器的分布式
文章来源于我的 iteye blog http://ak478288.iteye.com/blog/1898190 以前为部门内部开发过一个定时器程序,这个定时器很简单,就是配置quartz,来实现定 ...
- Redis分布式锁
Redis分布式锁 分布式锁是许多环境中非常有用的原语,其中不同的进程必须以相互排斥的方式与共享资源一起运行. 有许多图书馆和博客文章描述了如何使用Redis实现DLM(分布式锁管理器),但是每个库都 ...
- redis分布式锁和消息队列
最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP ...
- redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- Redis分布式锁的正确实现方式
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
随机推荐
- Ubuntu16.04 flask + nginx + uWSGI 部署
前言 又有段时间没写博客了,最近一直在写外包项目,都没啥空余时间.这几天花了不少时间做项目部署,也看了不少教程,这里就记录下整个过程,也方便以后要做类似部署的时候不用再查来查去了. flask + u ...
- 在linux下执行git clone、git pull 、git push等操作免密
1. 通过ssh密钥实现 ssh-keygen -t rsa -C "你的邮箱" -f "自己定义的目录" 打开: id_rsa.pub ,将文件内容复制到 g ...
- protus中出现invalid internal memory size ==NULL
点击8086芯片,更改internal memory size的大小为0x10000
- JS 如何获取自定义属性
<script>var testEle = document.getElementById("test"); testEle.setAttribute("de ...
- Hyperledger Fabric——balance transfer(五)执行交易
链码安装和实例化之后就可以调用chaincode执行交易,下面分析简单的账户转账操作是如何完成的. 源码分析 1.首先看app.js的路由函数 app.post('/channels/:channel ...
- UVA10779 Collectors Problem
题目链接:https://cn.vjudge.net/problem/UVA-10779 前言: 本题是关于姜志豪<网络流的一些建模方法>的笔记. 知识点: 最大流 题意摘抄: \(Bob ...
- Poj2586 每五个月都是亏
题目大意: MS公司(我猜是微软)遇到了千年虫的问题,导致数据大量数据丢失.比如财务报表.现在知道这个奇特的公司每个月不是盈利就是亏损(废话),而且无论是盈利和亏损都有一个定值(亏少了它还不干).经过 ...
- 换个角度学习ASP.NET Core中间件
中间件真面目 关于ASP.NET Core中间件是啥,简单一句话描述就是:用来处理HTTP请求和响应的一段逻辑,并且可以决定是否把请求传递到管道中的下一个中间件! 上面只是概念上的一种文字描述,那问题 ...
- SQL——AUTO INCREMENT(字段自增)
AUTO INCREMENT -- 在新记录插入表中时生成一个唯一的数字.插入表数据时,该字段不需规定值. 在每次插入新记录时,自动地创建主键字段的值.在表中创建一个 auto-incremen ...
- PHP SQL预处理
php预处理查询 $query='insert into p1(info) values(?)'; $query2='select info from p1 where id=?'; $country ...