Redis系列-生产应用篇-分布式锁(5)-单进程Redis分布式锁的Java实现(Redisson使用与底层实现)-原子锁类
Redisson单进程Redis分布式乐观锁的使用与实现
本文基于Redisson 3.7.5
4. 原子锁类
Redisson中实现了两种原子锁类:RAtomicLong和RAtomicDouble,还有RLongAdder和RDoubleAdder
RAtomicDouble和RAtomicLong其实一样的,RLongAdder和RDoubleAdder其实原理也是一样的,这里我们只说RAtomicLong和RLongAdder。
4.1. RedissonAtomicLong - 基于Redis实现的原子Long类
原子类的incrementAndGet,decrementAndGet,addandGet,主要通过INCR,DECR,INCRBY,DECRBY实现,其实redis的这些操作本身就是原子性的。
@Override
public RFuture<Long> getAndAddAsync(final long delta) {//getAndAdd通过INCRBY实现return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, new RedisStrictCommand<Long>("INCRBY", new SingleConvertor<Long>() {@Overridepublic Long convert(Object obj) {return ((Long) obj) - delta;}}), getName(), delta);
}
@Override
public RFuture<Long> getAndSetAsync(long newValue) {//getAndSet通过GetSet实现return commandExecutor.writeAsync(getName(), LongCodec.INSTANCE, RedisCommands.GETSET, getName(), newValue);
}
@Override
public RFuture<Long> incrementAndGetAsync() {//incrementAndGet通过INCR实现return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, RedisCommands.INCR, getName());
}
@Override
public RFuture<Long> decrementAndGetAsync() {//减一通过DECR实现return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, RedisCommands.DECR, getName());
}
那么CAS更新呢?可以利用lua脚本的特性,也就是因为redis是单线程的,同时只能处理一个lua脚本,所以lua脚本具有原子性。
@Override
public RFuture<Boolean> compareAndSetAsync(long expect, long update) {//CAS操作//通过lua脚本的特性实现,lua脚本的原子性//先检查值是否符合,如果符合再更新,返回true,否则返回falsereturn commandExecutor.evalWriteAsync(getName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,"local currValue = redis.call('get', KEYS[1]); "+ "if currValue == ARGV[1] "+ "or (tonumber(ARGV[1]) == 0 and currValue == false) then "+ "redis.call('set', KEYS[1], ARGV[2]); "+ "return 1 "+ "else "+ "return 0 "+ "end",Collections.<Object>singletonList(getName()), expect, update);
}
4.2. RedissonLongAdder 基于Redis实现的LongAdder
在统计场景下(写多读少,且数值不用考虑并发安全),LongAdder表现比AtomicLong更好,那么基于redis是怎么实现呢?
Redisson的实现思路比较简单,本地留存一个longAdder,只有调用get或者sum的时候,才把本地的longAdder的数值加到redis中。
public class RedissonLongAdder extends RedissonBaseAdder<Long> implements RLongAdder {//利用RAtomicLong实现redis中保存的数值private final RAtomicLong atomicLong;//本地longAdderprivate final LongAdder counter = new LongAdder();
}
统计但不get的操作都是对于本地longAdder操作:
@Override
public void add(long x) {counter.add(x);
}@Override
public void increment() {add(1L);
}@Override
public void decrement() {add(-1L);
}
与get还有sum相关的操作会把本地longAdder的数值加到redis中:
@Override
protected RFuture<Long> addAndGetAsync() {return atomicLong.getAndAddAsync(counter.sum());
}
@Override
protected RFuture<Long> getAndDeleteAsync() {return atomicLong.getAndDeleteAsync();
}
@Override
public long sum() {return get(sumAsync());
}
Redis系列-生产应用篇-分布式锁(5)-单进程Redis分布式锁的Java实现(Redisson使用与底层实现)-原子锁类相关推荐
- Redis系列-第四篇持久化与事务
一.持久化 Redis是一个内存数据库,为了保证数据的持久性,它提供了两种持久化方案: RDB方式(默认) AOF方式 持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的 ...
- 《Redis系列第三篇、incr与decr使用|CSDN创作打卡》
incr与decr的效率要高于set操作,故而个人在开发过程中用作高并发的时候的限制器,效果非常nice的. 接下来看看具体用法与官方解释啊. incr自增·将存储的key数字加一 使用方法 incr ...
- Redis系列教程(八):分布式锁的由来、及Redis分布式锁的实现详解
在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务.分布式锁等.那具体什么是分布式锁,分布式锁应用在哪些业务场景.如何来实现分布式锁呢?今天来探讨分布式锁这个话题. ...
- Redis教程--redis分布式锁+企业解决方案+redis实战
Redis,目前全国甚至是全球最常用的缓存中间件之一,在现在公司的开发中,可以说是离不开Redis. 在企业越来越注重用户体验的今天,Redis因具有高性能.高响应的特性,大大提升应用的响应速度和用户 ...
- Redis系列教程(五):Redis哨兵、复制、集群的设计原理,以及区别
前一篇文章高并发架构系列:Redis为什么是单线程.及高并发快的3大原因详解谈了Redis高并发快的3个原因,本篇主要谈Redis的高可用,两篇合起来就可以把redis的高并发和高可用搞清楚了. 谈到 ...
- Redis系列教程(三):如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
Java相关的面试都会问到缓存的问题:史上最全Redis面试49题(含答案):哨兵+复制+事务+集群+持久化等,除此之外还会问到缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级等不常见的问题,但却是非 ...
- Redis系列内容完整版
文章目录 Redis系列之_Redis介绍安装配置 第一章 redis初识 1.1 Redis是什么 1.2 Redis特性(8个) 1.3 Redis单机安装 1.3.1下载安装 1.3.2三种启动 ...
- 2020年11个Redis系列高频面试题,哪些你还不会?
前言 现在大家的工作生活基本已经是回归正轨了,最近也是迎来了跳槽面试季,有些人已经拿到了一两个offer了. 这段时间收集了阿里.腾讯.百度.京东.美团.字节跳动等公司的Java面试题,总结了Redi ...
- Redis系列教程(四):Redis为什么是单线程、及高并发快的3大原因详解
Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...
- Redis系列教程(七):Redis并发竞争key的解决方案详解
Redis高并发的问题 Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题: 高并发架构系列:Redis缓存和MySQL数据一致性方案详解 如何解决Redis缓 ...
最新文章
- python浪漫代码-使用Python代码的程序员也浪漫
- 2021.02.04 Visual QA论文阅读
- 热点的ap频段哪个快_WLAN中无线AP信道的划分
- 边际概率条件概率_数据科学家解释的边际联合和条件概率
- 程序员谈网络改变我们的生活
- Z-Stack Home Developer's Guide—6. Clusters, Commands and Attributes中文翻译【Z-Stack Home 1.2.0的开发文档】
- TensorFlow2.0(四)--Keras构建深度神经网络(DNN)
- 辞去程序员一职,我后悔了吗?
- webstrom默认是白色背景,如何修改
- JAVA访问控制权限
- dbt(data build tool) is an open source data transformation, and using Jinji templating
- windows搭建wordpress方法-windows搭建wordpress教程
- Word2007、Word2010、Word2013空格变成小点解决
- php图片留白,PHP:图片不变形处理(留白处理与截取处理)-奇乐网
- JAVA将日期类型(xx年xx月xx日)转化 成字符串变量
- 2022安全员-B证操作证考试题库及答案
- Delphi 把字符串复制到剪贴板
- java内存可视化_JVM系列(六)、可视化工具介绍
- vmm_xactor
- SpelResolverConfigurationOnMissingBean.spelResolver 找不到方法问题
热门文章
- mysql中获取时间的年月日_MySQL如何获取一个指定日期中的年份信息(YEAR函数)呢?...
- 关于电脑突然蓝屏后,重启idea报错HttpServlet不存在的问题
- bash ps1变量_Shell PS1变量:命令提示符设置
- ue字符编码_用ultraedit实现编码转换
- 重庆2021年高考二诊成绩查询,2021年重庆二诊,2021年4月重庆二诊考试,重庆二诊康德卷...
- 程序员面试注意几点就够了
- 新编计算机组装与维护教程,新编计算机组装与维护教程/21世纪高等学校计算机科学与技术规划教材...
- 最快下月!地表最强语言模型GPT-4发布在即?CEO暗示:已通过图灵测试
- matlab练习程序(图像放大/缩小,双线性插值)
- uniapp 日期时间 计算