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分布锁相关推荐

  1. 造了一个 Redis 分布锁的轮子,没想到还学到这么多东西!!!

    手撸分布式锁 这篇文章本来是准备写下 Mysql 查询左匹配的问题,但是还没研究出来.那就先写下最近在鼓捣一个东西,使用 Redis 实现可重入分布锁. 看到这里,有的朋友可能会提出来使用 redis ...

  2. Redis分布锁原理简介和实现过程

    前言 这篇文章介绍下如何实现redis来实现分布式锁及原理简介 原理简介 redis 获取分布式锁使用lua脚本的命令 setnx pexpire(提供了毫秒的过期时间,expire提供了基于秒的过期 ...

  3. redis分布式锁 在集群模式下如何实现_收藏慢慢看系列:简洁实用的Redis分布式锁用法...

    在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2. ...

  4. 深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!

    ‍‍‍‍‍‍‍‍‍‍‍‍阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了 ...

  5. 简洁实用的Redis分布式锁用法

    在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2. ...

  6. 深度剖析:Redis 分布式锁到底安全吗?看完这篇文章彻底懂了!

    作者 | Kaito 来源 | 水滴与银弹 阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题 ...

  7. 万字长文剖析Redis分布式锁到底安不安全

    ‍‍‍‍‍‍‍‍‍‍‍‍阅读本文大约需要 20 分钟. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了,我为什么还要写这篇文章呢? ...

  8. Redis分布式锁失效场景分析

    本文主要介绍了分布式锁失效的三种场景,并通过一些案例进行分析 背景 最近在项目中发现一些因为错误使用Redis分布式锁导致锁失效的问题.在此整理了一下使用分布式锁时要注意的点. 什么是分布式锁 分布式 ...

  9. 在线实时大数据平台Storm集成redis开发(分布锁)

    1.需求场景:spout从ftp列表中拿到未读取的文件读取并发射行到Bolt,bolt进行业务处理后提交下一Bolt入库.用redis主要是:保存文件列表对象,使用分布锁来同步互斥访问共享对象,使文件 ...

最新文章

  1. 敏捷个人:激励   2011-11-26期
  2. 线程间到底共享了哪些进程资源
  3. Xamarin Essentials教程数据处理传输数据
  4. gns3 查看网关_gns3常用命令
  5. leetcode - Same Tree
  6. java core日志在哪里_java-如何在未启用日志记录功能的情况下在...
  7. 用Python发送邮件[zt]
  8. HTML5 使用 JS 生成二维码,带头像
  9. ***从菜鸟到大虾教程下载
  10. 让 Python 代码运行更快的最佳方式!
  11. Query意图分析:记一次完整的机器学习过程(scikit learn library学习笔记)
  12. 利用PUT方式上传文件的方法研究
  13. 复现nature communication PCA原图|代码分析(一)
  14. luogu P1020 导弹拦截
  15. ssr使用mysql数据库_MySQL数据库安装与配置详解
  16. 互联网+创新创业大赛反思总结
  17. jQuery实现二级下拉菜单
  18. 只需用Shift键就能提升Mac开机速度的三个方法
  19. 使用python的turtle库画表情包
  20. 京东商品搜索架构设计

热门文章

  1. java领域对象_java的几种对象(po,dto,dao等)
  2. win2003服务器定时自动重启命令[计划任务]
  3. Golang 匿名结构体及测试代码编写技巧
  4. 304 Not Modified
  5. Java NIO:IO与NIO的区别
  6. Maven无法上传到到私服
  7. 第七章 移动自动化持续化集成(下)
  8. 隐藏头视图即隐藏UINavigationBar
  9. Linux很有用的根据字符串查找符合条件的命令
  10. 关于ark取得进程的镜像文件路径