分布式锁 基于Redis
分布式锁的实现(基于Redis)
参考:http://www.jb51.net/article/75439.htm
http://www.linuxidc.com/Linux/2015-01/111827.htm
http://www.tuicool.com/articles/6juqmm7
方式一: 基于第三方类库 redssion
1.安装redis
安装redssion的锁服务队redis的版本有要求,要求必须高于2.6版本。关于redis的安装,请参考redis安装。
2.redssion库
redssion的库添加的pom文件中去。
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>2.1.0</version></dependency>
3.测试例子
Config config = new Config(); config.useSingleServer().setAddress("ipaddress:6379"); Redisson redisson = Redisson.create(config); for(int i=0;i<5;i++){ RLock lock = redisson.getLock("testLock"); lock.lock(10, TimeUnit.SECONDS);//10s超时 logger.info("the lock client id is client{}",i); Thread.sleep(1000); logger.info("client{} unlock",i); lock.unlock(); }
4.参考
redisson
方式二: 自定义代码实现
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import redis.clients.jedis.Jedis; /** * redis实现的分布式锁 */public final class Lock { private static final String LOCK = "redis:lock:%s"; private static final int EXPIRE = 20 * 60;//20分钟 private static final Logger logger = LoggerFactory.getLogger(Lock.class); private Lock() { } public static Lock getLock() {return new Lock(); } /** * 获得锁,超时退出 * @param id * @param timeout 超时时间(ms) * @return */ public boolean lock(String id, int timeout) { //这里的Jedis实际上是个代理。代理类JedisCallback,JedisFactoryBean Jedis jedisProxy = JedisProxy.create(); long lock = 0; long start = System.currentTimeMillis(); while (lock != 1) {long now = System.currentTimeMillis(); //判断超时 if (timeout > 0 && now > start + timeout) {return false; }long timestamp = now + EXPIRE * 1000 + 1; try { String key = String.format(LOCK, id); lock = jedisProxy.setnx(key, String.valueOf(timestamp)); if (lock == 1) {logger.info("设置redis锁key成功,lock key=" + key); jedisProxy.expire(key, EXPIRE); logger.info("设置redis锁key过期时间成功,lock key=" + key); } else { String s = jedisProxy.get(key); Long lastLockTime = Long.parseLong(s); //一个项目部署多个服务,锁可能已经被相同定时任务的其他进程获得,则直接返回false if (jedisProxy.ttl(key)!=-1&&lastLockTime > System.currentTimeMillis()){logger.info("redis锁已经被其他服务获得,lock key=" + key); return false; }/** * 如果上次锁定的时间已经过期,则清除key锁,以便定时任务能够启动 * 造成未能释放的原因主要是jedis.expire(key, EXPIRE);失败 * 或者是获取锁之后,由于程序错误或网络错误,unlock未被成功调用 */ if (jedisProxy.ttl(key)==-1||lastLockTime < System.currentTimeMillis()) { jedisProxy.del(key); continue; }// this.wait(100); Thread.sleep(100); } } catch (Exception e) {logger.error("从redis获取定时任务锁错误,key="+String.format(LOCK, id), e); return false; } }return true; } /** * 释放锁 * @param id */ public void unLock(String id) { //这里的Jedis实际上是个代理。代理类JedisCallback,JedisFactoryBean Jedis jedisProxy = JedisProxy.create(); String key = String.format(LOCK, id); jedisProxy.del(key); }}
JedisProxy类
/** * Jedis代理 */@Componentpublic class JedisProxy implements ApplicationContextAware { private static volatile ApplicationContext ac; /** * 创建Jedis 代理 * * @return */ public static Jedis create() {return ac.getBean(Jedis.class); } @Override public void setApplicationContext(ApplicationContext applicationContext) {if (ac != null) {return; }synchronized (JedisProxy.class) {if (ac != null) {return; }ac = applicationContext; } }}
转载于:https://www.cnblogs.com/wangdaijun/p/5301858.html
分布式锁 基于Redis相关推荐
- redis 分布式锁 看门狗_漫谈分布式锁之Redis实现
笔耕墨耘,深研术道. 01写在前面Redis是一个高性能的内存数据库,常用于数据库.缓存和消息中间件.它提供了丰富的数据结构,更适合各种业务场景:基于AP模型,Redis保证了其高可用和高性能. 本文 ...
- Redis核心数据结构List应用场景-商品列表、缓存击穿、PV阅读量、抢红包、推送帖子、普通分布式锁、Redis可重入锁与红锁
List应用场景 Redis之List 一. Redis list命令实战 二.商品列表 高并发的淘宝聚划算实现技术方案 SpringBoot+Redis实现商品列表功能 二.缓存击穿 什么是缓存击穿 ...
- 分布式锁用 Redis 还是 Zookeeper?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:jianfeng 来源:石杉的架构笔记 为什么用分布式锁? ...
- 什么是分布式锁?redis、zookeeper、etcd实现分布式锁有什么不同之处?
目录 分布式锁定义 目的 基于redis分布式锁 基于zookeeper实现的分布式锁 edis.zookeeper.etcd实现分布式锁的比较 建议选择etcd实现分布式锁 分布式锁定义 分布式环境 ...
- 分布式锁用Redis还是Zookeeper?
为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景. 作者:jianfeng来源:石杉的架构笔记|2019-07-16 09:22 为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场 ...
- java如何保证redis设置过期时间的原子性_分布式锁用 Redis 还是 Zookeeper
在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单. 由于系统有 ...
- 分布式锁用Redis坚决不用Zookeeper?
墨墨导读:为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景. 为什么用分布式锁? 系统 A 是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查 ...
- redis中有key但是删不掉_分布式锁用 Redis 还是 Zookeeper
为什么用分布式锁? 在讨论这个问题之前,我们先来看一个业务场景:系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户 ...
- Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析Redis分布式锁的正确使用姿势!...
Redis分布式锁基本原理 采用 redis 实现分布式锁,主要是利用其单线程命令执行的特性,一般是 setnx, 只会有一个线程会执行成功,也就是只有一个线程能成功获取锁:看着很完美. 然而-- 看 ...
最新文章
- linux下jdk简单配置记录
- 项目使用mysql接收emoji表情
- 表变量是什么_为什么要使用二级指针?
- 关于捕获键盘信息的processDialogkey方法2--具体应用
- 【九省联考2018】秘密袭击【树形dp】【生成函数】【线段树合并】【多项式插值】
- php 403 nginx,403nginx是什么
- SQL Server 2005中的SQLCMD工具使用
- ifound Android wifi,方正新品记录仪iFound V1号称黑夜变白天,真的假的?
- Java不支持创建范型数组分析
- draw9patch做一个中心不变形的图片
- AC9560网卡linux驱动安装
- 计算机组成原理第五章考试题,计算机组成原理第五章部分课后题答案(唐朔飞版).doc...
- 你想要的宏基因组-微生物组知识全在这(2021.3)
- RubyOnRails杂记
- google广告推广提示有恶意软件链接的处理方案
- [分析力学]解题思路 - 拉格朗日方程
- GIS应用技巧之环形地图制作
- [unity] build项目报错:Currently selected scripting backend (.NET)is not installed
- 爬取沪江网考研词汇并按要求存为txt
- ESP8266(ESP模块)Arduino开发环境快速搭建方法--含网盘离线文件
热门文章
- 【Hihocoder - 1723】子树统计(线性基合并)
- 【POJ - 1661】Help Jimmy(记忆化搜索,dp)
- priority_queue(优先队列)的简单构造与用法
- 视觉SLAM十四讲(1):预备知识
- 遍历这些字符串,如果字符串没有包含数字的, * 就将字符串中的小写字母转成大写字母并打印字符串
- Linux简单命令收录(cal,passwd,clear)【下】
- Redis:18---常用功能之(Lua脚本)
- GCC在C语言中内嵌汇编 asm __volatile__
- nginx python webpy 配置安装
- openssl里面AES算法主要函数的参数的介绍