redisson中的分布式锁二

公平锁(Fair Lock)

基于Redis的Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。所有请求线程会在一个队列中排队,当某个线程出现宕机时,Redisson会等待5秒后继续下一个线程,也就是说如果前面有5个线程都处于等待状态,那么后面的线程会等待至少25秒。

RLock fairLock = redisson.getFairLock("anyLock");
// 最常见的使用方法
fairLock.lock();

// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
fairLock.lock(10, TimeUnit.SECONDS);

// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
fairLock.unlock();

联锁(MultiLock)

基于Redis的Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁,每个RLock对象实例可以来自于不同的Redisson实例。

RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");

RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
// 同时加锁:lock1 lock2 lock3
// 所有的锁都上锁成功才算成功。
lock.lock();
...
lock.unlock();

红锁(RedLock)

基于Redis的Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例。

RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");

RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
// 同时加锁:lock1 lock2 lock3
// 红锁在大部分节点上加锁成功就算成功。
lock.lock();
...
lock.unlock();

读写锁(ReadWriteLock)

基于Redis的Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks.ReadWriteLock接口。其中读锁和写锁都继承了RLock接口。

分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。

RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
// 最常见的使用方法
rwlock.readLock().lock();
// 或
rwlock.writeLock().lock();

// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// 或
rwlock.writeLock().lock(10, TimeUnit.SECONDS);

// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// 或
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();

添加StockController方法:

@GetMapping("test/read")
public String testRead(){
    String msg = stockService.testRead();

    return "测试读";
}

@GetMapping("test/write")
public String testWrite(){
    String msg = stockService.testWrite();

    return "测试写";
}

添加StockService方法:

public String testRead() {
    RReadWriteLock rwLock = this.redissonClient.getReadWriteLock("rwLock");
    rwLock.readLock().lock(10, TimeUnit.SECONDS);

    System.out.println("测试读锁。。。。");
    // rwLock.readLock().unlock();

    return null;
}

public String testWrite() {
    RReadWriteLock rwLock = this.redissonClient.getReadWriteLock("rwLock");
    rwLock.writeLock().lock(10, TimeUnit.SECONDS);

    System.out.println("测试写锁。。。。");
    // rwLock.writeLock().unlock();

    return null;
}

打开开两个浏览器窗口测试:

  • 同时访问写:一个写完之后,等待一会儿(约10s),另一个写开始
  • 同时访问读:不用等待
  • 先写后读:读要等待(约10s)写完成
  • 先读后写:写要等待(约10s)读完成

信号量(Semaphore)

基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。

RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.trySetPermits(3);
semaphore.acquire();
semaphore.release();

在StockController添加方法:

@GetMapping("test/semaphore")
public String testSemaphore(){
    this.stockService.testSemaphore();

    return "测试信号量";
}

在StockService添加方法:

public void testSemaphore() {
    RSemaphore semaphore = this.redissonClient.getSemaphore("semaphore");
    semaphore.trySetPermits(3);
    try {
        semaphore.acquire();

        TimeUnit.SECONDS.sleep(5);
        System.out.println(System.currentTimeMillis());

        semaphore.release();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

添加测试用例:并发10次,循环一次

在这里插入图片描述

控制台效果:

控制台1:
1606960790234
1606960800337
1606960800443
1606960805248

控制台2:
1606960790328
1606960795332
1606960800245

控制台3:
1606960790433
1606960795238
1606960795437

由此可知:

1606960790秒有3次请求进来:每个控制台各1次

1606960795秒有3次请求进来:控制台2有1次,控制台3有2次

1606960800秒有3次请求进来:控制台1有2次,控制台2有1次

1606960805秒有1次请求进来:控制台1有1次

闭锁(CountDownLatch)

基于Redisson的Redisson分布式闭锁(CountDownLatch)Java对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。

RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();

// 在其他线程或其他JVM里
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();

需要两个方法:一个等待,一个计数countDown

给StockController添加测试方法:

@GetMapping("test/latch")
public String testLatch(){
    this.stockService.testLatch();

    return "班长锁门。。。";
}

@GetMapping("test/countdown")
public String testCountDown(){
    this.stockService.testCountDown();

    return "出来了一位同学";
}

给StockService添加测试方法:

public void testLatch() {
    RCountDownLatch latch = this.redissonClient.getCountDownLatch("latch");
    latch.trySetCount(6);

    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void testCountDown() {
    RCountDownLatch latch = this.redissonClient.getCountDownLatch("latch");
    latch.trySetCount(6);

    latch.countDown();
}

重启测试,打开两个页面:当第二个请求执行6次之后,第一个请求才会执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/126691.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YB1205B S0T23开关式异步升压具恒压恒流LED驱动器

YB1205B S0T23开关式异步升压具恒压恒流LED驱动器 产品简介: YB1205B是一种输入电压范围宽(0.85.5V),可调恒定电流和限定电流两种模式来驱动白光LED而设计的升压型DCDC变换器。采用变频模式,逐周期限流,使输入输出电流随电源电压降低均匀变…

微服务之Nacos注册管理

文章目录 一、Nacos安装步骤1.安装地址2.安装版本3.目录说明4.端口配置5.启动 二、Nacos服务注册1.Nacos依赖2.客户端修改配置文件3.启动效果图4.总结 三、Nacos服务集群属性1.服务跨集群调用问题2.服务集群属性3.总结 四、Nacos根据集群负载均衡1.修改配置文件2.设置集群服务类…

【C语法学习】20 - 文件访问顺序

文章目录 0 前言1 文件位置指示符2 rewind()函数2.1 函数原型2.2 参数2.3 返回值2.4 使用说明 3 ftell()函数3.1 函数原型3.2 参数3.3 返回值 4 fseek()函数4.1 函数原型4.2 参数4.3 返回值 5 示例5.1 示例15.2 示例2 0 前言 C语言文件访问分为顺序文件访问和随机文件访问。 …

Kotlin库实现多线程爬取数据

由于字数限制,以下是一个简化版的爬虫程序示例,使用了Kotlin的网络库kotlinx.coroutines和kotlinx.html。这个程序会爬取一个简单的Python多线程跑数据的网页,并打印出结果。 import kotlinx.coroutines.* import kotlinx.html.* import java…

oracle-sql语句解析类型

语句执行过程:1. 解析(将sql解析成执行计划) 2.执行 3.获取数据(fetch) 1. shared pool的组成。 share pool是一块内存池。 主要分成3块空间。free, library(库缓存,缓存sql以及执行计划),row cache(字典缓存) select * from v…

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)

注解目录 第二章《c语言的一些“操作”及其深层理解》 一、字符串的实质就是指针 (如何将 35 转为对应的十六进制字符串”0X23”?) 二 、转义符\ (打入字符串内部的“奸细”。) 三、字符串常量的连接 &#xff…

WebSocket在node端和客户端的使用

摘要 如果想要实现一个聊天的功能,就会想到使用WebSocket来搭建。那如果没有WebSocet的时候,我们会以什么样的思路来实现聊天功能呢? 假如有一个A页面 和 B页面进行通信,当A发送信息后,我们可以将信息存储在文件或者…

Vue 最简单路由 页面路由 配置路由

路由安装 Vue3使用 vue-router4 Vue2使用 vue-router3 npm i vue-router3创建路由文件 配置路由规则 import Vue from vue import VueRouter from vue-router //导入路由器 Vue.use(VueRouter)import Login from ../components/Login import User from ../components/User //…

服务器数据恢复—云服务器mysql数据库表被truncate的数据恢复案例

云服务器数据恢复环境: 阿里云ECS网站服务器,linux操作系统mysql数据库。 云服务器故障: 在执行数据库版本更新测试时,在生产库误执行了本来应该在测试库执行的sql脚本,导致生产库部分表被truncate,还有部…

基于springboot实现福聚苑社区团购平台系统项目【项目源码】

基于springboot实现福聚苑社区团购平台系统演示 Javar技术 Java是一种网络脚本语言,广泛运用于web应用开发,可以用来添加网页的格式动态效果,该语言不用进行预编译就直接运行,可以直接嵌入HTML语言中,写成js语言&…

如何在时间循环里最优决策——时间旅行者的最优决策

文章目录 每日一句正能量前言时间旅行和平行宇宙强化学习策略梯度算法代码案例推荐阅读赠书活动 每日一句正能量 做一个决定,并不难,难的是付诸行动,并且坚持到底。 前言 时间循环是一类热门的影视题材,其设定常常如下&#xff1…

javaSE学习笔记(四)常见类,基本数据类型包装类,StringBufferStringBuilder

目录 三、面向对象 16.Object类 方法 和equals() 17.String类 注意 构造方法 String的最大长度 String的底层存储结构 字符串的常量池机制 String类的方法 String类的判断功能 String类的获取功能 String类的转换功能 String类拼接 String类的其他功能 18.Math…

vue3 自动导入composition-apiI和组件

1.api的自动导入 常规写法&#xff1a; <script setup>import { ref, reactive, onMounted, computed ,watch } from vue;import { useRouter } from "vue-router";const router useRouter();const person reactive ({name&#xff1a;张三&#xff0c;age…

美国Embarcadero公司正式发布2023 RAD Studio Delphi C++ Builder 12 Athens

Embarcadero 非常高兴地宣布发布 RAD Studio 12 Athens 以及 Delphi 12 和 CBuilder 12。RAD Studio 12 Athens 版本包含令人兴奋的新功能&#xff0c;为该产品的未来奠定了基础。 目录 主要新功能 C 的奇妙之处Delphi 的一些不错的补充FireMonkey 和 Skia 作为新基金会采用 MD…

观测云产品更新 | 数据转发、监控器告警策略等优化

数据转发 数据查询时间组件优化&#xff0c;支持选择多个日期&#xff0c;并可以自定义开始时间和结束时间&#xff0c;时间精确到小时。 监控器 > 告警策略优化 1、「通知配置」逻辑调整为&#xff1a;针对单个异常等级配置通知单个或多个对象告警通知。 2、「恢复通知」…

使用XnView MP快速查看图片某个像素点的RGB像素值

效果图 如上图lena.png X:28 Y:9 RGB (220, 129, 107) HTML(#dc816b) 简介 XnView MP是一款非常著名的免费看图软件XnView 的新版本 MP是 Multi Platform 的缩写&#xff0c;支持多平台并基于同样的源代码&#xff0c;不同平台也提供统一的界面和体验&#xff0c;最终取代…

Java使用FTP连接到NAS读取文件信息,并将文件信息变成单向树形结构设置到对象中

检测NAS是否启用的FTP连接模式 如果这里不启用会出现下面错误提示&#xff1a; MalformedServerReplyException: Could not parse response code. Server Reply: SSH-2.0-OpenS 使用依赖 <dependency><groupId>commons-net</groupId><artifactId>comm…

每次重启完IDEA,application.properties文件里的中文变成?

出现这种情况&#xff0c;在IDEA打开Settings-->Editor-->File Encodings 然后&#xff0c;你需要将问号改为你需要的汉字。 重启IDEA&#xff0c;再次查看你的.properties文件就会发现再没有变成问号了

在Node.js中,什么是Promise?如何使用Promise处理异步操作?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

Word脚注如何插入?1分钟学会!

“最近在写一些文章&#xff0c;引用了一些注释&#xff0c;想为它们增添一些脚注。有没有朋友知道在word里脚注怎么添加呀&#xff1f;” 使用word编写文章时&#xff0c;添加脚注是一项常见的任务&#xff0c;用于引用文献、添加注释或提供额外信息。但可能很多朋友不知道wor…