分布式锁实现方案2、基于Redis的SET操作实现的分布式锁

2023-11-19

继上一篇文章 分布式锁实现方案1、基于Redis的SETNX操作实现的分布式锁 实现方案之后,redis又提供了更加强大的set方法,可以解决分布式锁实现方案1中提到的缺陷,直接看代码

package com.alioo.lock;

import com.jd.jim.cli.Cluster;

import java.util.concurrent.TimeUnit;

/**
 * <pre>
 * 基于Redis的SET操作实现的分布式锁
 * </pre>
 *
 * @author lzc.java@icloud.com
 *
 */
public class RedisDistributedLock2 {

    private Cluster redis;

    // 锁的名字
    private String lockKey;

    private boolean locked;

    // 当前jvm内持有该锁的线程(if have one)
    private Thread exclusiveOwnerThread;

    /**
     *
     * @param redis
     * @param lockKey  lockKey
     * @throws java.io.IOException
     */
    public RedisDistributedLock2(Cluster redis, String lockKey ) {
        this.redis = redis;
        this.lockKey = lockKey;
    }

    /**
     * 阻塞式获取锁 ,不过有超时时间,超过了tryGetLockTime还未获取到锁将直接返回false
     *
     * @param tryGetLockTime
     * @param tryGetLockUnit
     * @return
     */
    protected boolean lock(long tryGetLockTime, TimeUnit tryGetLockUnit) {
        try {
            // 超时控制 的时间可以从本地获取, 因为这个和锁超时没有关系, 只是一段时间区间的控制
            long start = System.currentTimeMillis();
            long timeout = tryGetLockUnit.toMillis(tryGetLockTime);

            while (System.currentTimeMillis() - start < timeout) {
                long lockExpireTime = System.currentTimeMillis() + timeout + 1;//锁超时时间
                String stringOfLockExpireTime = String.valueOf(lockExpireTime);

               boolean flag= redis.set(lockKey, stringOfLockExpireTime, tryGetLockTime, tryGetLockUnit, false);
                if (flag) { // 获取到锁, 设置相关标识
                    locked = true;
                    exclusiveOwnerThread = Thread.currentThread();
                    return true;
                }
                Thread.sleep(5L);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 非阻塞,立即返回是否获取到锁
     * @return
     */
    public boolean tryLock(long tryGetLockTime, TimeUnit tryGetLockUnit) {
        long timeout = tryGetLockUnit.toMillis(tryGetLockTime);
        long lockExpireTime = System.currentTimeMillis() + timeout + 1;//锁超时时间
        String stringOfLockExpireTime = String.valueOf(lockExpireTime);

        boolean flag= redis.set(lockKey, stringOfLockExpireTime, tryGetLockTime, tryGetLockUnit , false);
        if (flag) { // 获取到锁, 设置相关标识
            locked = true;
            exclusiveOwnerThread = Thread.currentThread();
            return true;
        }
        return false;
    }

    public boolean isLocked() {
        return locked;
    }

    /**
     * 释放锁
     */
    public void unlock() {
        // 检查当前线程是否持有锁
        if (Thread.currentThread() != exclusiveOwnerThread) {
            // 表明锁并非当前线程所持有,不应该由当前线程来释放锁
            System.out.println("锁并非当前线程所持有,放弃释放锁exclusiveOwnerThread:" + exclusiveOwnerThread + ",Thread.currentThread():" + Thread.currentThread() + ",lockKey" + lockKey);
            return;
        }

        redis.del(lockKey);
        exclusiveOwnerThread = null;
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分布式锁实现方案2、基于Redis的SET操作实现的分布式锁 的相关文章

  • 在 Java Swing 中检测 JScrollPane 上的 mouseClick 事件

    如果我有这样的东西 我可以使用布尔标志 performAdjustment 控制自动滚动 static boolean performAdjustment true JTextArea textArea new JTextArea JScr
  • 如何在java swing中的每个页面中打印带有页脚的整个JPanel

    好吧 这可能很简单 但想不通 我有一个包含 JTable 的 JPanel JTable 包含很少的行 有时更多 因为我推入其中的表模型取决于数据库 但是 我不使用任何包含 JTable 的 JScolpane 因此 当 JTable 包含
  • JPanel透明背景和显示元素[重复]

    这个问题在这里已经有答案了 我插入一个背景图e 变成 aJPanel但一些界面元素消失了 以下 Java Swing 元素不会出现 标签标题 标签 usuario 标签 密码 按钮加速器 你能否使图像透明或元素不透明 setOpaque f
  • 如何在Spring的applicationContext.xml中指定默认范围来请求范围?

    我想让所有 bean 请求默认作用域 但是 Spring 文档说默认作用域是 Singleton 第 3 4 1 和 3 4 2 节http static springsource org spring docs 2 5 x referen
  • 无法从后台服务通过 WiFi 访问互联网

    我将直接介绍我发现的一些事实 数据 如果您遇到 解决了类似的问题 请帮助我 我每 5 分钟向服务器发送一次数据 除非用户在服务器的帮助下手动将其关闭 wakeful broadcast receiver通过一个intent service
  • 在 Spring 中设置 WS https 调用超时 (HttpsUrlConnectionMessageSender)

    我正在尝试为 WS 调用设置超时 我延长了WebServiceGatewaySupport并尝试将发送者超时设置为如下 public Object marshalSendAndReceive Object requestPayload We
  • 会话 bean 中的 EntityManager 异常处理

    我有一个托管无状态会话 bean 其中注入了 EntityManager em 我想做的是拥有一个具有唯一列的数据库表 然后我运行一些尝试插入实体的算法 但是 如果实体存在 它将更新它或跳过它 我想要这样的东西 try em persist
  • JSP 标签+ scriptlet。如何启用脚本?

    我有一个使用标签模板的页面 我的 web xml 非常基本 我只是想在页面中运行一些代码 不 我对标签或其他替代品不感兴趣 我想使用不好的做法 scriptlet 哈哈 到目前为止 我收到了 HTTP ERROR 500 错误 Script
  • java JFileChooser 文件大小过滤器

    我知道我可以按文件类型进行过滤 但是可以按文件大小进行过滤吗 例如 JFileChooser 仅显示 3 MB 以内的图片 简短的回答应该是 你尝试过什么 长答案是肯定的 JFileChooser fc new JFileChooser f
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • 通用 JSF 实体转换器[重复]

    这个问题在这里已经有答案了 我正在编写我的第一个 Java EE 6 Web 应用程序作为学习练习 我没有使用框架 只是使用 JPA 2 0 EJB 3 1 和 JSF 2 0 我有一个自定义转换器 用于将存储在 SelectOne 组件中
  • 当容器大小更改时,JTable 仅调整选定列的大小

    对于面板内的 JTable 如果面板变大 我如何将额外的空间仅分配给某些列 在我的例子中 分配给最后一列 尽管提供 第 3 4 列和8 将获得额外的空间 我想允许用户手动更改所有列的列大小 我尝试了 table setAutoResizeM
  • 嵌入式 tomcat 7 servlet 3.0 注释不起作用

    我有一个精简的测试项目 其中包含 Servlet 版本 3 0 用注释声明 如下所示 WebServlet test public class TestServlet extends HttpServlet private static f
  • 用 Java 创建迷宫求解算法

    我被分配了用 Java 创建迷宫求解器的任务 这是任务 Write an application that finds a path through a maze The maze should be read from a file A
  • 如何计算文件中单词的长度?爪哇

    我正在尝试编写一个代码来计算文件中特定长度的单词数 例如 How are you 会打印 Proportion of 3 letter words 100 3 words 我想计算长度为 1 2 3 4 5 6 7 8 9 10 11 12
  • 使用 Maven 3 时 Cobertura 代码覆盖率为 0%

    读完这篇文章后 将 Cobertura 与 Maven 3 0 2 一起使用的正确方法是什么 https stackoverflow com questions 6931360 what is the proper way to use c
  • Scala repl 抛出错误

    当我打字时scala在终端上启动 repl 它会抛出此错误 scala gt init error error while loading AnnotatedElement class file usr lib jvm java 8 ora
  • 监控 Java 应用程序上的锁争用

    我正在尝试创建一个小基准 在 Groovy 中 以显示几个同步方法上的高线程争用 当监控自愿上下文切换时 应该会出现高争用 在 Linux 中 这可以通过 pidstat 来实现 程序如下 class Res private int n s
  • 日期时间解析异常

    解析日期时 我的代码中不断出现异常错误 日期看起来像这样 Wed May 21 00 00 00 EDT 2008 这是尝试读取它的代码 DateTimeFormatter formatter DateTimeFormatter ofPat
  • 如何使用 Spring AOP 建议静态方法?

    在执行类的静态方法之前和之后需要完成一些日志记录 我尝试使用 Spring AOP 来实现这一点 但它不起作用 而对于正常方法来说它起作用 请帮助我理解如何实现这一点 如果可以使用注释来完成 那就太好了 也许您应该在使用 Spring AO

随机推荐

  • SpringBoot配置多数据源,三数据源,mysql+oracle+mysql

    废话不多说 直接上代码 yml文件配置 server port 8080 spring datasource primary
  • 小谈设计模式(1)—总序

    小谈设计模式 1 总序 专栏地址 开始操作 设计模式总论 设计模式是什么 组成要素 模式名称 问题描述 解决方案 效果描述 设计模式有什么作用 提供可重用的解决方案 提高代码的可读性和可维护性 促进代码的可扩展性 提高代码的灵活性和可重用性
  • llvm之IR手册翻译(5)

    原网址是 http llvm org docs LangRef html abstract 下面这些是我自己的翻译 肯定有很多不恰当的地方 做这些只是希望自己以后翻阅更加方便 如果能对大家有所帮助那是极好的 别名 别名 不像函数或变量 不会
  • OSError:...libcublasLt.so.11 with link time reference

    程序运行时报错 OSError u01 anaconda3 envs modlscope py39 lib python3 9 site packages nvidia cublas lib libcublas so 11 symbol c
  • 无法从命令行或调试器启动服务,必须首先安装Windows服务....。在“安装”阶段发生异常。 System.Security.SecurityException:未找到源

    此处一共两个问题 第一个问题完整描述是 无法从命令行或调试器启动服务 必须首先安装Windows服务 使用installutil exe 然后用ServerExplorer Windows服务器管理工具或NET START命令启动它 第二个
  • Python基础教程:强大的Pandas数据分析库

    Pandas是一个基于 NumPy 的非常强大的开源数据处理库 它提供了高效 灵活和丰富的数据结构和数据分析工具 当涉及到数据分析和处理时 使得数据清洗 转换 分析和可视化变得更加简单和高效 本文中 我们将学习如何使用Pandas来处理和分
  • 集合addAll方法使用存在的问题。

    集合addAll 方法的时候 这里里有两个集合 集合2要拿到集合1中的元素 然后对集合2进行removeAll方法 结果集合1中的值也没有了 只是因为listTwo listOne 只是把集合1的引用给了集合2 集合1和集合2的引用是指向同
  • GDB and Reverse Debugging

    Overview GDB version 7 0 due September 2009 will be the first public release of gdb to support reverse debugging the abi
  • PTA基础题练习-检查密码

    PTA 检查密码 本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能 该网站要求用户设置的密码必须由不少于6个字符组成 并且只能有英文字母 数字和小数点 还必须既有字母也有数字 输出格式 输入样例 输出样例 本题要求你帮助某网站
  • Linux学习(一):查看文件目录的几种常用方式

    一 将主文件夹下的所有文件列出来 包括属性与隐藏文件 完整呈现文件的修改时间 注意 无论如何 ls最长被使用到的功能还是那个 l的参数 为此很多distribution在默认的情况中 已经将ll l的小写 设置成为ls l的意思了 这个功能
  • kodi没有中文设置_kodi播放器设置中文的方法

    KODI播放器是一款强大的多媒体播放器 其能够支持目前几乎所有的主流格式文件的播放 而且除了视频文件外 即使是音乐 图片 电视节目等其他媒体文件也能够正常进行播放 而且能够支持投屏扥更种辅助功能 为用户提供了一套完整的播放方案 因而广受用户
  • zookeeper学习草稿纸

    指令重排序 https baijiahao baidu com s id 1701616903992143186 wfr spider for pc JVM JDK JRE 静态方法为什么不能调用非静态成员 重载和重写的区别 可变参数 基本
  • 高质量、高并发的实时通信架构设计与探索

    中国互联网络信息中心 CNNIC 近日发布的第 47 次 中国互联网络发展状况统计报告 显示 截至 2020 年 12 月 我国网民规模达 9 89 亿 随着社会信息化水平持续提升及电子设备加速普及 手机网民规模持续增长 基本实现对全体网民
  • 关于Semaphore信号量的源码解读

    Semaphore的简单使用 利用Semaphore可以实现对线程数量的控制 比如如下的代码 class SemaphoreTest public static void main String args Semaphore semapho
  • 【RTX 3060Ti 深度学习环境配置图文(安装Anaconda、VScode、CUDA、CUDNN、pytorch)】

    RTX 3060Ti 深度学习环境配置图文 安装Anaconda VScode CUDA CUDNN pytorch 配置 安装驱动 一 安装Anaconda 1 1 Anaconda简介 1 2 下载Anaconda 1 3安装Anaco
  • SpringBoot集成jasypt,加密yml配置文件

    SpringBoot集成jasypt 加密yml配置文件 一 pom配置 二 生成密文代码 三 配置 3 1 yml加密配置 3 2 密文配置 3 3 启动配置 3 4 部署配置 四 遇到的一些坑 最新项目安全检测 发现配置文件中数据库密码
  • Spring学习笔记day01——Spring入门

    Spring学习 Spring介绍 1 1Spring概述 Spring是一个开源框架 Spring是于2003 年兴起的一个轻量级的Java 开发框架 由Rod Johnson 在其著作Expert One On One J2EE Dev
  • 设计模式的 C++ 实现---工厂方法模式(二)

    前文回顾 单例模式 一 单例模式 二 观察者模式 简单工厂模式 工厂方法模式 一 前言 对于工厂方法模式 当增加新产品时 也需要对应增加一个工厂类 可以使用模版进行封装 减少代码工作量 实现举例 产品抽象基类 class Animal pu
  • TypeScript 基本概念

    TypeScript 是什么 目标 能够说出什么是 TypeScript TS 官方文档 TS 中文参考 不再维护 TypeScript 简称 TS 是 JavaScript 的超集 JS 有的 TS 都有 TypeScript Type
  • 分布式锁实现方案2、基于Redis的SET操作实现的分布式锁

    继上一篇文章 分布式锁实现方案1 基于Redis的SETNX操作实现的分布式锁 实现方案之后 redis又提供了更加强大的set方法 可以解决分布式锁实现方案1中提到的缺陷 直接看代码 package com alioo lock impo