1 锁的业务场景
在商品秒杀、车票抢购等高并发场景中,确保同一时刻仅有一个线程扣减库存,避免因并发操作导致库存数量错误(如库存扣减为负数)。
单机锁:synchronized、Lock、CAS
高并发场景下肯定是分布式部署,单机锁无法完成需求,就需要分布式锁
2 靠谱分布式锁具备的条件
① 独占性:任何时候只能有且仅有一个线程持有锁
② 高可用:不能因为某个节点挂了而不能提供服务
③ 防死锁:杜绝死锁,必须有超时控制和撤销操作的兜底方案
④ 不乱抢:不能私下unlock别人的锁,只能自己加锁自己释放
⑤ 可重入:同一个节点的同一个线程如果获得锁之后,他还可以再次获取这个锁
3 分布式锁实现
3.1 MySQL(基于数据库实现)
通过数据库的排他锁实现(select * from table where id=xx for update)
缺点:实现非常简单但性能比较低,不适应高并发场景
3.2 基于Redis
3.2.1 思考的几个问题
① 最简单的实现:setnx key value
② 如何避免死锁:设置过期时间
③ 锁不能被别人释放:通过value判断
④ 锁过期不好评估:看门狗线程
3.2.2 操作思路
① 加锁:set key value ex time nx
② 业务处理
③ 释放锁(lua脚本,保证原子性),先get判断锁是否属于自己,在删除
3.2.3 代码实现
@Component
@Slf4j
public class RedisLock {
/*保存每个线程的独有的I