java分布式锁

什么是分布式锁?[面试8.0]

分布式锁:
保证分布式环境下多个线程同时对一个共享变量进行修改或删除时加一把锁,该锁能保证同一时间只能有一个线程在操作

分布式锁有哪些实现方式?[面试8.0]

基于数据库的悲观锁和乐观锁实现
数据库悲观锁: for update实现(要注意语句针对行级时,如果where条件的字段不走索引,那么会锁整个表)
缺点:
会造成其他线程阻塞,有锁表的风险,吞吐量低,适用于写多的场景
锁定失败后需要用轮询(while循环)继续锁定,这样的话占用CPU资源
数据库乐观锁: 表添加version字段解决,更新时先查询旧版本出来,更新版本号+1并且where条件需要=旧版本号
Redis分布式锁: 利用setnx实现
Zookeeper分布式锁: 创建顺序性的虚拟节点实现的公平锁

使用Redis作为分布式锁怎么实现?[面试9.5]

setIfAbsent:
使用Spring的setIfAbsent(即redis的setnx方法)
将解锁操作放到finally中确保程序崩掉后能释放(防止死锁)
在setnx时同时设置超时时间用来防止机器宕机后没有自动释放锁(防止死锁)
解锁时通过线程Id或UUID判断是否是当前线程所加的锁,若是才解锁(防止由于业务程序超时解了其他线程的锁)

getset(延期策略):
程序用来防止程序没执行完该key就过期的问题
程序会每隔一定时间检查一下该线程的该key是否还存在,若存在就将该Key的过期时间延长(延长为一个和之前等长的新的过期时间)
注意: 还可以通过Redisson来实现,内部做了封装(默认超时时间是30秒)
redis-分布式锁-诸葛
redisson-分布式锁原理-诸葛

使用Redis作为分布式锁会出现什么问题?[面试9.5]

死锁问题:
程序即将运行完会解锁,但这时宕机,锁还没有释放,就会出现死锁
解了其他线程的锁:
多线程的情况下,由于程序超时Redis提前解了锁导致->下一个线程进来却被解了锁,而之前线程尚未解锁
延时导致的并发问题:
多线程的情况下,由于程序超时Redis提前解了锁,这种情况下需要采用延期策略(getset)

集群锁丢失问题:
还有就是关于Redis集群怎么防止Master和Slave由于中途Master宕机,Slave没来得及复制锁的情况,目前的解决方式是使用RedLock但有些争议,建议使用Zookeeper的分布式锁来解决

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2023年Java面试宝典

您的鼓励是对我的肯定,共建希望

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值