分布式锁
-
线程安全问题:多线程,共享资源,非原子性操作;同一时间,同一资源
-
i++不是原子性操作,是一组操作,三步操作
1.从主存读值
2.+1操作
3.刷写到内存
A B 都想执行i++
A 获取CPU资源 时间片形式
A 2ms B 5ms
会导致数据更新出问题
解决:synchronized
各种悲观锁:多线程并行=>单线程串行
A没用完不让B用
sync:堆,线程共享区,锁对象,int count = 0; 默认互斥量为0
lock:AQS volatile static int state = 0; 默认互斥量也为0
可见,互斥量 int
//单机锁互斥原理
if (count/state == 0){
count/state = 1;//获取锁成功
//一顿操作
count/state = 0;
//唤醒别人
} else {
//获取锁失败,挂起线程并加入队列等待
}
分布式锁
获取锁:相同目录创建一个文件夹,mkdir /usr/lock/
释放锁:rm -rf /usr/lock/
只有一个线程能成功在一个路径创建这个文件夹,其他线程等待
redis实现
只有一个线程能 set 成功,f 为 true
finally,即使中间断了也会释放锁,但是断电了还是执行不了,所以要给锁加一个 timeout 过期时间,过时间自动删除了
图中第 4 行执行后断电,第 5 行没有执行,一直占用锁怎么办
//写到一行了,具有原子性
Boolean f = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, timeout);
业务时间超过锁的 timeout 时间咋办(ABC问题)
给锁加上唯一标识,自己上的锁只有自己能解开,具体操作:
String lockValue = UUID.randomUUID.toString();
但是业务还是跑不完啊,怎么办(AB问题)
开子线程(守护线程)续命,监视到主线程死了/业务结束了,结束自己;主线程死了:锁 timeout 释放 / 业务结束了:finally 释放锁
守护线程:
主从架构锁失效
redis 高性能 电商:
zookeeper 高稳定 金融:主服务器知道你想上锁后,把这个消息发给从服务器,从服务器有一半以上都知道你上锁了,上锁才能成功(分布式锁,投票上锁?)
分布式锁基于单机锁推导,悲观锁
redisson用法
并发那么高,分布式锁性能得多慢,怎么解决
1.降低锁粒度,多余的业务别放锁里啊,不同的对象别用一个锁啊,加了不同业务的独立 id
2.分段容器,每个数据做分段,甚至细到每个数据,每个数据的每个字段,整体架构优化
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!