Java实现Redis分布锁
1、背景:
在多线程环境下,通常会使用锁来保证有且只有一个线程来操作共享资源。比如:
object obj = new object();
lock (obj)
{
//操作共享资源
}
利用操作系统提供的锁机制,可以确保多线程或多进程下的并发唯一操作。但如果在多机环境下就不能满足了,当A,B两台机器同时操作C机器的共享资源时,就需要第三方的锁机制来保证在分布式环境下的资源协调,也称分布式锁。
在分布式环境下(多节点主机)加锁处理场景,如:秒杀、全局递增ID等等,需要对资源(变量)同步互斥。大部分的解决方案是基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。由于Redis是单线程模型,命令操作原子性,所以利用这个特性可以很容易的实现分布式锁。
2、Redis有三个最基本属性来保证分布式锁的有效实现:
安全性: 互斥,在任何时候,只有一个客户端能持有锁。
活跃性A:没有死锁,即使客户端在持有锁的时候崩溃,最后也会有其他客户端能获得锁,超时机制。
活跃性B:故障容忍,只有大多数Redis节点时存活的,客户端仍可以获得锁和释放锁。
使用Redis实现分布式锁,有两个重要函数需要介绍
1)SETNX命令(SET if Not eXists)
语法:
SETNX key value
功能:
当且仅当 key 不存在,将 key 的值设为 value ,并返回1;若给定的 key 已经存在,则 SETNX 不做任何动作,并返回0。
2)GETSET命令
语法:
GETSET key value
功能:
将给定 key 的值设为 value ,并返回 key 的旧值 (old value),当 key 存在但不是字符串类型时,返回一个错误,当key不存在时,返回nil。
3、代码:
package ct.tool;import redis.clients.jedis.Jedis;public class RedisDisLock {private static final long expired = 1000;//1秒超时//上锁public static boolean acquireLock(Jedis jedis,String lock) {// 1. 通过SETNX试图获取一个lockboolean success = false;long value = System.currentTimeMillis() + expired + 1; long acquired = jedis.setnx(lock, String.valueOf(value));jedis.expire(lock, 1);//设置1秒超时//SETNX成功,则成功获取一个锁if (acquired == 1) success = true;//SETNX失败,说明锁被其他客户端保持,检查其是否已经超时/*else {long oldValue = Long.valueOf(jedis.get(lock)); if (oldValue < System.currentTimeMillis()) {//超时//获取上一个锁到期时间,并设置现在的锁到期时间,//只有一个线程才能获取上一个线上的设置时间,因为jedis.getSet是同步的String getValue = jedis.getSet(lock, String.valueOf(value));if (getValue !=null) {if (Long.valueOf(getValue) == oldValue) success = true; else success = false;// 已被其他进程捷足先登了} }else //未超时,则直接返回失败success = false;} */return success; }//释放锁public static void releaseLock(Jedis jedis,String lock) { //long current = System.currentTimeMillis(); // 避免删除非自己获取得到的锁//if (current < Long.valueOf(jedis.get(lock)))jedis.del(lock); }}
代码应用中,要共享的代码段前加:
//枷锁boolean lockFlag=true;while(lockFlag){//循环等待拿锁if (RedisDisLock.acquireLock(jd,"o2o")) lockFlag=false;}
业务处理后,释放:
RedisDisLock.releaseLock(jd, "o2o");
Java实现Redis分布锁相关推荐
- 造了一个 Redis 分布锁的轮子,没想到还学到这么多东西!!!
手撸分布式锁 这篇文章本来是准备写下 Mysql 查询左匹配的问题,但是还没研究出来.那就先写下最近在鼓捣一个东西,使用 Redis 实现可重入分布锁. 看到这里,有的朋友可能会提出来使用 redis ...
- Redis分布锁原理简介和实现过程
前言 这篇文章介绍下如何实现redis来实现分布式锁及原理简介 原理简介 redis 获取分布式锁使用lua脚本的命令 setnx pexpire(提供了毫秒的过期时间,expire提供了基于秒的过期 ...
- redis分布式锁 在集群模式下如何实现_收藏慢慢看系列:简洁实用的Redis分布式锁用法...
在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2. ...
- 深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!
阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了 ...
- 简洁实用的Redis分布式锁用法
在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2. ...
- 深度剖析:Redis 分布式锁到底安全吗?看完这篇文章彻底懂了!
作者 | Kaito 来源 | 水滴与银弹 阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题 ...
- 万字长文剖析Redis分布式锁到底安不安全
阅读本文大约需要 20 分钟. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了,我为什么还要写这篇文章呢? ...
- Redis分布式锁失效场景分析
本文主要介绍了分布式锁失效的三种场景,并通过一些案例进行分析 背景 最近在项目中发现一些因为错误使用Redis分布式锁导致锁失效的问题.在此整理了一下使用分布式锁时要注意的点. 什么是分布式锁 分布式 ...
- 在线实时大数据平台Storm集成redis开发(分布锁)
1.需求场景:spout从ftp列表中拿到未读取的文件读取并发射行到Bolt,bolt进行业务处理后提交下一Bolt入库.用redis主要是:保存文件列表对象,使用分布锁来同步互斥访问共享对象,使文件 ...
最新文章
- 敏捷个人:激励 2011-11-26期
- 线程间到底共享了哪些进程资源
- Xamarin Essentials教程数据处理传输数据
- gns3 查看网关_gns3常用命令
- leetcode - Same Tree
- java core日志在哪里_java-如何在未启用日志记录功能的情况下在...
- 用Python发送邮件[zt]
- HTML5 使用 JS 生成二维码,带头像
- ***从菜鸟到大虾教程下载
- 让 Python 代码运行更快的最佳方式!
- Query意图分析:记一次完整的机器学习过程(scikit learn library学习笔记)
- 利用PUT方式上传文件的方法研究
- 复现nature communication PCA原图|代码分析(一)
- luogu P1020 导弹拦截
- ssr使用mysql数据库_MySQL数据库安装与配置详解
- 互联网+创新创业大赛反思总结
- jQuery实现二级下拉菜单
- 只需用Shift键就能提升Mac开机速度的三个方法
- 使用python的turtle库画表情包
- 京东商品搜索架构设计